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-2017, 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 <time.h>
22 : #include <unistd.h>
23 :
24 : #include "libpq-fe.h"
25 : #include "libpq-int.h"
26 : #include "fe-auth.h"
27 : #include "pg_config_paths.h"
28 :
29 : #ifdef WIN32
30 : #include "win32.h"
31 : #ifdef _WIN32_IE
32 : #undef _WIN32_IE
33 : #endif
34 : #define _WIN32_IE 0x0500
35 : #ifdef near
36 : #undef near
37 : #endif
38 : #define near
39 : #include <shlobj.h>
40 : #ifdef _MSC_VER /* mstcpip.h is missing on mingw */
41 : #include <mstcpip.h>
42 : #endif
43 : #else
44 : #include <sys/socket.h>
45 : #include <netdb.h>
46 : #include <netinet/in.h>
47 : #ifdef HAVE_NETINET_TCP_H
48 : #include <netinet/tcp.h>
49 : #endif
50 : #include <arpa/inet.h>
51 : #endif
52 :
53 : #ifdef ENABLE_THREAD_SAFETY
54 : #ifdef WIN32
55 : #include "pthread-win32.h"
56 : #else
57 : #include <pthread.h>
58 : #endif
59 : #endif
60 :
61 : #ifdef USE_LDAP
62 : #ifdef WIN32
63 : #include <winldap.h>
64 : #else
65 : /* OpenLDAP deprecates RFC 1823, but we want standard conformance */
66 : #define LDAP_DEPRECATED 1
67 : #include <ldap.h>
68 : typedef struct timeval LDAP_TIMEVAL;
69 : #endif
70 : static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
71 : PQExpBuffer errorMessage);
72 : #endif
73 :
74 : #include "common/ip.h"
75 : #include "mb/pg_wchar.h"
76 :
77 :
78 : #ifndef WIN32
79 : #define PGPASSFILE ".pgpass"
80 : #else
81 : #define PGPASSFILE "pgpass.conf"
82 : #endif
83 :
84 : /*
85 : * Pre-9.0 servers will return this SQLSTATE if asked to set
86 : * application_name in a startup packet. We hard-wire the value rather
87 : * than looking into errcodes.h since it reflects historical behavior
88 : * rather than that of the current code.
89 : */
90 : #define ERRCODE_APPNAME_UNKNOWN "42704"
91 :
92 : /* This is part of the protocol so just define it */
93 : #define ERRCODE_INVALID_PASSWORD "28P01"
94 : /* This too */
95 : #define ERRCODE_CANNOT_CONNECT_NOW "57P03"
96 :
97 : /*
98 : * Cope with the various platform-specific ways to spell TCP keepalive socket
99 : * options. This doesn't cover Windows, which as usual does its own thing.
100 : */
101 : #if defined(TCP_KEEPIDLE)
102 : /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
103 : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
104 : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
105 : #elif defined(TCP_KEEPALIVE_THRESHOLD)
106 : /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */
107 : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
108 : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
109 : #elif defined(TCP_KEEPALIVE) && defined(__darwin__)
110 : /* TCP_KEEPALIVE is the name of this option on macOS */
111 : /* Caution: Solaris has this symbol but it means something different */
112 : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
113 : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
114 : #endif
115 :
116 : /*
117 : * fall back options if they are not specified by arguments or defined
118 : * by environment variables
119 : */
120 : #define DefaultHost "localhost"
121 : #define DefaultTty ""
122 : #define DefaultOption ""
123 : #define DefaultAuthtype ""
124 : #define DefaultTargetSessionAttrs "any"
125 : #ifdef USE_SSL
126 : #define DefaultSSLMode "prefer"
127 : #else
128 : #define DefaultSSLMode "disable"
129 : #endif
130 :
131 : /* ----------
132 : * Definition of the conninfo parameters and their fallback resources.
133 : *
134 : * If Environment-Var and Compiled-in are specified as NULL, no
135 : * fallback is available. If after all no value can be determined
136 : * for an option, an error is returned.
137 : *
138 : * The value for the username is treated specially in conninfo_add_defaults.
139 : * If the value is not obtained any other way, the username is determined
140 : * by pg_fe_getauthname().
141 : *
142 : * The Label and Disp-Char entries are provided for applications that
143 : * want to use PQconndefaults() to create a generic database connection
144 : * dialog. Disp-Char is defined as follows:
145 : * "" Normal input field
146 : * "*" Password field - hide value
147 : * "D" Debug option - don't show by default
148 : *
149 : * PQconninfoOptions[] is a constant static array that we use to initialize
150 : * a dynamically allocated working copy. All the "val" fields in
151 : * PQconninfoOptions[] *must* be NULL. In a working copy, non-null "val"
152 : * fields point to malloc'd strings that should be freed when the working
153 : * array is freed (see PQconninfoFree).
154 : *
155 : * The first part of each struct is identical to the one in libpq-fe.h,
156 : * which is required since we memcpy() data between the two!
157 : * ----------
158 : */
159 : typedef struct _internalPQconninfoOption
160 : {
161 : char *keyword; /* The keyword of the option */
162 : char *envvar; /* Fallback environment variable name */
163 : char *compiled; /* Fallback compiled in default value */
164 : char *val; /* Option's current value, or NULL */
165 : char *label; /* Label for field in connect dialog */
166 : char *dispchar; /* Indicates how to display this field in a
167 : * connect dialog. Values are: "" Display
168 : * entered value as is "*" Password field -
169 : * hide value "D" Debug option - don't show
170 : * by default */
171 : int dispsize; /* Field size in characters for dialog */
172 : /* ---
173 : * Anything above this comment must be synchronized with
174 : * PQconninfoOption in libpq-fe.h, since we memcpy() data
175 : * between them!
176 : * ---
177 : */
178 : off_t connofs; /* Offset into PGconn struct, -1 if not there */
179 : } internalPQconninfoOption;
180 :
181 : static const internalPQconninfoOption PQconninfoOptions[] = {
182 : /*
183 : * "authtype" is no longer used, so mark it "don't show". We keep it in
184 : * the array so as not to reject conninfo strings from old apps that might
185 : * still try to set it.
186 : */
187 : {"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
188 : "Database-Authtype", "D", 20, -1},
189 :
190 : {"service", "PGSERVICE", NULL, NULL,
191 : "Database-Service", "", 20, -1},
192 :
193 : {"user", "PGUSER", NULL, NULL,
194 : "Database-User", "", 20,
195 : offsetof(struct pg_conn, pguser)},
196 :
197 : {"password", "PGPASSWORD", NULL, NULL,
198 : "Database-Password", "*", 20,
199 : offsetof(struct pg_conn, pgpass)},
200 :
201 : {"passfile", "PGPASSFILE", NULL, NULL,
202 : "Database-Password-File", "", 64,
203 : offsetof(struct pg_conn, pgpassfile)},
204 :
205 : {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
206 : "Connect-timeout", "", 10, /* strlen(INT32_MAX) == 10 */
207 : offsetof(struct pg_conn, connect_timeout)},
208 :
209 : {"dbname", "PGDATABASE", NULL, NULL,
210 : "Database-Name", "", 20,
211 : offsetof(struct pg_conn, dbName)},
212 :
213 : {"host", "PGHOST", NULL, NULL,
214 : "Database-Host", "", 40,
215 : offsetof(struct pg_conn, pghost)},
216 :
217 : {"hostaddr", "PGHOSTADDR", NULL, NULL,
218 : "Database-Host-IP-Address", "", 45,
219 : offsetof(struct pg_conn, pghostaddr)},
220 :
221 : {"port", "PGPORT", DEF_PGPORT_STR, NULL,
222 : "Database-Port", "", 6,
223 : offsetof(struct pg_conn, pgport)},
224 :
225 : {"client_encoding", "PGCLIENTENCODING", NULL, NULL,
226 : "Client-Encoding", "", 10,
227 : offsetof(struct pg_conn, client_encoding_initial)},
228 :
229 : /*
230 : * "tty" is no longer used either, but keep it present for backwards
231 : * compatibility.
232 : */
233 : {"tty", "PGTTY", DefaultTty, NULL,
234 : "Backend-Debug-TTY", "D", 40,
235 : offsetof(struct pg_conn, pgtty)},
236 :
237 : {"options", "PGOPTIONS", DefaultOption, NULL,
238 : "Backend-Debug-Options", "D", 40,
239 : offsetof(struct pg_conn, pgoptions)},
240 :
241 : {"application_name", "PGAPPNAME", NULL, NULL,
242 : "Application-Name", "", 64,
243 : offsetof(struct pg_conn, appname)},
244 :
245 : {"fallback_application_name", NULL, NULL, NULL,
246 : "Fallback-Application-Name", "", 64,
247 : offsetof(struct pg_conn, fbappname)},
248 :
249 : {"keepalives", NULL, NULL, NULL,
250 : "TCP-Keepalives", "", 1, /* should be just '0' or '1' */
251 : offsetof(struct pg_conn, keepalives)},
252 :
253 : {"keepalives_idle", NULL, NULL, NULL,
254 : "TCP-Keepalives-Idle", "", 10, /* strlen(INT32_MAX) == 10 */
255 : offsetof(struct pg_conn, keepalives_idle)},
256 :
257 : {"keepalives_interval", NULL, NULL, NULL,
258 : "TCP-Keepalives-Interval", "", 10, /* strlen(INT32_MAX) == 10 */
259 : offsetof(struct pg_conn, keepalives_interval)},
260 :
261 : {"keepalives_count", NULL, NULL, NULL,
262 : "TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */
263 : offsetof(struct pg_conn, keepalives_count)},
264 :
265 : /*
266 : * ssl options are allowed even without client SSL support because the
267 : * client can still handle SSL modes "disable" and "allow". Other
268 : * parameters have no effect on non-SSL connections, so there is no reason
269 : * to exclude them since none of them are mandatory.
270 : */
271 : {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
272 : "SSL-Mode", "", 12, /* sizeof("verify-full") == 12 */
273 : offsetof(struct pg_conn, sslmode)},
274 :
275 : {"sslcompression", "PGSSLCOMPRESSION", "1", NULL,
276 : "SSL-Compression", "", 1,
277 : offsetof(struct pg_conn, sslcompression)},
278 :
279 : {"sslcert", "PGSSLCERT", NULL, NULL,
280 : "SSL-Client-Cert", "", 64,
281 : offsetof(struct pg_conn, sslcert)},
282 :
283 : {"sslkey", "PGSSLKEY", NULL, NULL,
284 : "SSL-Client-Key", "", 64,
285 : offsetof(struct pg_conn, sslkey)},
286 :
287 : {"sslrootcert", "PGSSLROOTCERT", NULL, NULL,
288 : "SSL-Root-Certificate", "", 64,
289 : offsetof(struct pg_conn, sslrootcert)},
290 :
291 : {"sslcrl", "PGSSLCRL", NULL, NULL,
292 : "SSL-Revocation-List", "", 64,
293 : offsetof(struct pg_conn, sslcrl)},
294 :
295 : {"requirepeer", "PGREQUIREPEER", NULL, NULL,
296 : "Require-Peer", "", 10,
297 : offsetof(struct pg_conn, requirepeer)},
298 :
299 : #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
300 : /* Kerberos and GSSAPI authentication support specifying the service name */
301 : {"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
302 : "Kerberos-service-name", "", 20,
303 : offsetof(struct pg_conn, krbsrvname)},
304 : #endif
305 :
306 : #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
307 :
308 : /*
309 : * GSSAPI and SSPI both enabled, give a way to override which is used by
310 : * default
311 : */
312 : {"gsslib", "PGGSSLIB", NULL, NULL,
313 : "GSS-library", "", 7, /* sizeof("gssapi") = 7 */
314 : offsetof(struct pg_conn, gsslib)},
315 : #endif
316 :
317 : {"replication", NULL, NULL, NULL,
318 : "Replication", "D", 5,
319 : offsetof(struct pg_conn, replication)},
320 :
321 : {"target_session_attrs", "PGTARGETSESSIONATTRS",
322 : DefaultTargetSessionAttrs, NULL,
323 : "Target-Session-Attrs", "", 11, /* sizeof("read-write") = 11 */
324 : offsetof(struct pg_conn, target_session_attrs)},
325 :
326 : /* Terminating entry --- MUST BE LAST */
327 : {NULL, NULL, NULL, NULL,
328 : NULL, NULL, 0}
329 : };
330 :
331 : static const PQEnvironmentOption EnvironmentOptions[] =
332 : {
333 : /* common user-interface settings */
334 : {
335 : "PGDATESTYLE", "datestyle"
336 : },
337 : {
338 : "PGTZ", "timezone"
339 : },
340 : /* internal performance-related settings */
341 : {
342 : "PGGEQO", "geqo"
343 : },
344 : {
345 : NULL, NULL
346 : }
347 : };
348 :
349 : /* The connection URI must start with either of the following designators: */
350 : static const char uri_designator[] = "postgresql://";
351 : static const char short_uri_designator[] = "postgres://";
352 :
353 : static bool connectOptions1(PGconn *conn, const char *conninfo);
354 : static bool connectOptions2(PGconn *conn);
355 : static int connectDBStart(PGconn *conn);
356 : static int connectDBComplete(PGconn *conn);
357 : static PGPing internal_ping(PGconn *conn);
358 : static PGconn *makeEmptyPGconn(void);
359 : static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
360 : static void freePGconn(PGconn *conn);
361 : static void closePGconn(PGconn *conn);
362 : static void release_all_addrinfo(PGconn *conn);
363 : static void sendTerminateConn(PGconn *conn);
364 : static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
365 : static PQconninfoOption *parse_connection_string(const char *conninfo,
366 : PQExpBuffer errorMessage, bool use_defaults);
367 : static int uri_prefix_length(const char *connstr);
368 : static bool recognized_connection_string(const char *connstr);
369 : static PQconninfoOption *conninfo_parse(const char *conninfo,
370 : PQExpBuffer errorMessage, bool use_defaults);
371 : static PQconninfoOption *conninfo_array_parse(const char *const *keywords,
372 : const char *const *values, PQExpBuffer errorMessage,
373 : bool use_defaults, int expand_dbname);
374 : static bool conninfo_add_defaults(PQconninfoOption *options,
375 : PQExpBuffer errorMessage);
376 : static PQconninfoOption *conninfo_uri_parse(const char *uri,
377 : PQExpBuffer errorMessage, bool use_defaults);
378 : static bool conninfo_uri_parse_options(PQconninfoOption *options,
379 : const char *uri, PQExpBuffer errorMessage);
380 : static bool conninfo_uri_parse_params(char *params,
381 : PQconninfoOption *connOptions,
382 : PQExpBuffer errorMessage);
383 : static char *conninfo_uri_decode(const char *str, PQExpBuffer errorMessage);
384 : static bool get_hexdigit(char digit, int *value);
385 : static const char *conninfo_getval(PQconninfoOption *connOptions,
386 : const char *keyword);
387 : static PQconninfoOption *conninfo_storeval(PQconninfoOption *connOptions,
388 : const char *keyword, const char *value,
389 : PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode);
390 : static PQconninfoOption *conninfo_find(PQconninfoOption *connOptions,
391 : const char *keyword);
392 : static void defaultNoticeReceiver(void *arg, const PGresult *res);
393 : static void defaultNoticeProcessor(void *arg, const char *message);
394 : static int parseServiceInfo(PQconninfoOption *options,
395 : PQExpBuffer errorMessage);
396 : static int parseServiceFile(const char *serviceFile,
397 : const char *service,
398 : PQconninfoOption *options,
399 : PQExpBuffer errorMessage,
400 : bool *group_found);
401 : static char *pwdfMatchesString(char *buf, char *token);
402 : static char *passwordFromFile(char *hostname, char *port, char *dbname,
403 : char *username, char *pgpassfile);
404 : static void pgpassfileWarning(PGconn *conn);
405 : static void default_threadlock(int acquire);
406 :
407 :
408 : /* global variable because fe-auth.c needs to access it */
409 : pgthreadlock_t pg_g_threadlock = default_threadlock;
410 :
411 :
412 : /*
413 : * pqDropConnection
414 : *
415 : * Close any physical connection to the server, and reset associated
416 : * state inside the connection object. We don't release state that
417 : * would be needed to reconnect, though.
418 : *
419 : * We can always flush the output buffer, since there's no longer any hope
420 : * of sending that data. However, unprocessed input data might still be
421 : * valuable, so the caller must tell us whether to flush that or not.
422 : */
423 : void
424 221 : pqDropConnection(PGconn *conn, bool flushInput)
425 : {
426 : /* Drop any SSL state */
427 221 : pqsecure_close(conn);
428 :
429 : /* Close the socket itself */
430 221 : if (conn->sock != PGINVALID_SOCKET)
431 217 : closesocket(conn->sock);
432 221 : conn->sock = PGINVALID_SOCKET;
433 :
434 : /* Optionally discard any unread data */
435 221 : if (flushInput)
436 221 : conn->inStart = conn->inCursor = conn->inEnd = 0;
437 :
438 : /* Always discard any unsent data */
439 221 : conn->outCount = 0;
440 :
441 : /* Free authentication state */
442 : #ifdef ENABLE_GSS
443 : {
444 : OM_uint32 min_s;
445 :
446 : if (conn->gctx)
447 : gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
448 : if (conn->gtarg_nam)
449 : gss_release_name(&min_s, &conn->gtarg_nam);
450 : }
451 : #endif
452 : #ifdef ENABLE_SSPI
453 : if (conn->sspitarget)
454 : {
455 : free(conn->sspitarget);
456 : conn->sspitarget = NULL;
457 : }
458 : if (conn->sspicred)
459 : {
460 : FreeCredentialsHandle(conn->sspicred);
461 : free(conn->sspicred);
462 : conn->sspicred = NULL;
463 : }
464 : if (conn->sspictx)
465 : {
466 : DeleteSecurityContext(conn->sspictx);
467 : free(conn->sspictx);
468 : conn->sspictx = NULL;
469 : }
470 : conn->usesspi = 0;
471 : #endif
472 221 : if (conn->sasl_state)
473 : {
474 : /*
475 : * XXX: if support for more authentication mechanisms is added, this
476 : * needs to call the right 'free' function.
477 : */
478 0 : pg_fe_scram_free(conn->sasl_state);
479 0 : conn->sasl_state = NULL;
480 : }
481 221 : }
482 :
483 :
484 : /*
485 : * Connecting to a Database
486 : *
487 : * There are now six different ways a user of this API can connect to the
488 : * database. Two are not recommended for use in new code, because of their
489 : * lack of extensibility with respect to the passing of options to the
490 : * backend. These are PQsetdb and PQsetdbLogin (the former now being a macro
491 : * to the latter).
492 : *
493 : * If it is desired to connect in a synchronous (blocking) manner, use the
494 : * function PQconnectdb or PQconnectdbParams. The former accepts a string of
495 : * option = value pairs (or a URI) which must be parsed; the latter takes two
496 : * NULL terminated arrays instead.
497 : *
498 : * To connect in an asynchronous (non-blocking) manner, use the functions
499 : * PQconnectStart or PQconnectStartParams (which differ in the same way as
500 : * PQconnectdb and PQconnectdbParams) and PQconnectPoll.
501 : *
502 : * Internally, the static functions connectDBStart, connectDBComplete
503 : * are part of the connection procedure.
504 : */
505 :
506 : /*
507 : * PQconnectdbParams
508 : *
509 : * establishes a connection to a postgres backend through the postmaster
510 : * using connection information in two arrays.
511 : *
512 : * The keywords array is defined as
513 : *
514 : * const char *params[] = {"option1", "option2", NULL}
515 : *
516 : * The values array is defined as
517 : *
518 : * const char *values[] = {"value1", "value2", NULL}
519 : *
520 : * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
521 : * if a memory allocation failed.
522 : * If the status field of the connection returned is CONNECTION_BAD,
523 : * then some fields may be null'ed out instead of having valid values.
524 : *
525 : * You should call PQfinish (if conn is not NULL) regardless of whether this
526 : * call succeeded.
527 : */
528 : PGconn *
529 217 : PQconnectdbParams(const char *const *keywords,
530 : const char *const *values,
531 : int expand_dbname)
532 : {
533 217 : PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
534 :
535 217 : if (conn && conn->status != CONNECTION_BAD)
536 215 : (void) connectDBComplete(conn);
537 :
538 217 : return conn;
539 :
540 : }
541 :
542 : /*
543 : * PQpingParams
544 : *
545 : * check server status, accepting parameters identical to PQconnectdbParams
546 : */
547 : PGPing
548 0 : PQpingParams(const char *const *keywords,
549 : const char *const *values,
550 : int expand_dbname)
551 : {
552 0 : PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
553 : PGPing ret;
554 :
555 0 : ret = internal_ping(conn);
556 0 : PQfinish(conn);
557 :
558 0 : return ret;
559 : }
560 :
561 : /*
562 : * PQconnectdb
563 : *
564 : * establishes a connection to a postgres backend through the postmaster
565 : * using connection information in a string.
566 : *
567 : * The conninfo string is either a whitespace-separated list of
568 : *
569 : * option = value
570 : *
571 : * definitions or a URI (refer to the documentation for details.) Value
572 : * might be a single value containing no whitespaces or a single quoted
573 : * string. If a single quote should appear anywhere in the value, it must be
574 : * escaped with a backslash like \'
575 : *
576 : * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
577 : * if a memory allocation failed.
578 : * If the status field of the connection returned is CONNECTION_BAD,
579 : * then some fields may be null'ed out instead of having valid values.
580 : *
581 : * You should call PQfinish (if conn is not NULL) regardless of whether this
582 : * call succeeded.
583 : */
584 : PGconn *
585 0 : PQconnectdb(const char *conninfo)
586 : {
587 0 : PGconn *conn = PQconnectStart(conninfo);
588 :
589 0 : if (conn && conn->status != CONNECTION_BAD)
590 0 : (void) connectDBComplete(conn);
591 :
592 0 : return conn;
593 : }
594 :
595 : /*
596 : * PQping
597 : *
598 : * check server status, accepting parameters identical to PQconnectdb
599 : */
600 : PGPing
601 0 : PQping(const char *conninfo)
602 : {
603 0 : PGconn *conn = PQconnectStart(conninfo);
604 : PGPing ret;
605 :
606 0 : ret = internal_ping(conn);
607 0 : PQfinish(conn);
608 :
609 0 : return ret;
610 : }
611 :
612 : /*
613 : * PQconnectStartParams
614 : *
615 : * Begins the establishment of a connection to a postgres backend through the
616 : * postmaster using connection information in a struct.
617 : *
618 : * See comment for PQconnectdbParams for the definition of the string format.
619 : *
620 : * Returns a PGconn*. If NULL is returned, a malloc error has occurred, and
621 : * you should not attempt to proceed with this connection. If the status
622 : * field of the connection returned is CONNECTION_BAD, an error has
623 : * occurred. In this case you should call PQfinish on the result, (perhaps
624 : * inspecting the error message first). Other fields of the structure may not
625 : * be valid if that occurs. If the status field is not CONNECTION_BAD, then
626 : * this stage has succeeded - call PQconnectPoll, using select(2) to see when
627 : * this is necessary.
628 : *
629 : * See PQconnectPoll for more info.
630 : */
631 : PGconn *
632 217 : PQconnectStartParams(const char *const *keywords,
633 : const char *const *values,
634 : int expand_dbname)
635 : {
636 : PGconn *conn;
637 : PQconninfoOption *connOptions;
638 :
639 : /*
640 : * Allocate memory for the conn structure
641 : */
642 217 : conn = makeEmptyPGconn();
643 217 : if (conn == NULL)
644 0 : return NULL;
645 :
646 : /*
647 : * Parse the conninfo arrays
648 : */
649 217 : connOptions = conninfo_array_parse(keywords, values,
650 : &conn->errorMessage,
651 : true, expand_dbname);
652 217 : if (connOptions == NULL)
653 : {
654 0 : conn->status = CONNECTION_BAD;
655 : /* errorMessage is already set */
656 0 : return conn;
657 : }
658 :
659 : /*
660 : * Move option values into conn structure
661 : */
662 217 : if (!fillPGconn(conn, connOptions))
663 : {
664 0 : PQconninfoFree(connOptions);
665 0 : return conn;
666 : }
667 :
668 : /*
669 : * Free the option info - all is in conn now
670 : */
671 217 : PQconninfoFree(connOptions);
672 :
673 : /*
674 : * Compute derived options
675 : */
676 217 : if (!connectOptions2(conn))
677 0 : return conn;
678 :
679 : /*
680 : * Connect to the database
681 : */
682 217 : if (!connectDBStart(conn))
683 : {
684 : /* Just in case we failed to set it in connectDBStart */
685 2 : conn->status = CONNECTION_BAD;
686 : }
687 :
688 217 : return conn;
689 : }
690 :
691 : /*
692 : * PQconnectStart
693 : *
694 : * Begins the establishment of a connection to a postgres backend through the
695 : * postmaster using connection information in a string.
696 : *
697 : * See comment for PQconnectdb for the definition of the string format.
698 : *
699 : * Returns a PGconn*. If NULL is returned, a malloc error has occurred, and
700 : * you should not attempt to proceed with this connection. If the status
701 : * field of the connection returned is CONNECTION_BAD, an error has
702 : * occurred. In this case you should call PQfinish on the result, (perhaps
703 : * inspecting the error message first). Other fields of the structure may not
704 : * be valid if that occurs. If the status field is not CONNECTION_BAD, then
705 : * this stage has succeeded - call PQconnectPoll, using select(2) to see when
706 : * this is necessary.
707 : *
708 : * See PQconnectPoll for more info.
709 : */
710 : PGconn *
711 0 : PQconnectStart(const char *conninfo)
712 : {
713 : PGconn *conn;
714 :
715 : /*
716 : * Allocate memory for the conn structure
717 : */
718 0 : conn = makeEmptyPGconn();
719 0 : if (conn == NULL)
720 0 : return NULL;
721 :
722 : /*
723 : * Parse the conninfo string
724 : */
725 0 : if (!connectOptions1(conn, conninfo))
726 0 : return conn;
727 :
728 : /*
729 : * Compute derived options
730 : */
731 0 : if (!connectOptions2(conn))
732 0 : return conn;
733 :
734 : /*
735 : * Connect to the database
736 : */
737 0 : if (!connectDBStart(conn))
738 : {
739 : /* Just in case we failed to set it in connectDBStart */
740 0 : conn->status = CONNECTION_BAD;
741 : }
742 :
743 0 : return conn;
744 : }
745 :
746 : /*
747 : * Move option values into conn structure
748 : *
749 : * Don't put anything cute here --- intelligence should be in
750 : * connectOptions2 ...
751 : *
752 : * Returns true on success. On failure, returns false and sets error message.
753 : */
754 : static bool
755 217 : fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
756 : {
757 : const internalPQconninfoOption *option;
758 :
759 6293 : for (option = PQconninfoOptions; option->keyword; option++)
760 : {
761 6076 : if (option->connofs >= 0)
762 : {
763 5642 : const char *tmp = conninfo_getval(connOptions, option->keyword);
764 :
765 5642 : if (tmp)
766 : {
767 2389 : char **connmember = (char **) ((char *) conn + option->connofs);
768 :
769 2389 : if (*connmember)
770 0 : free(*connmember);
771 2389 : *connmember = strdup(tmp);
772 2389 : if (*connmember == NULL)
773 : {
774 0 : printfPQExpBuffer(&conn->errorMessage,
775 : libpq_gettext("out of memory\n"));
776 0 : return false;
777 : }
778 : }
779 : }
780 : }
781 :
782 217 : return true;
783 : }
784 :
785 : /*
786 : * connectOptions1
787 : *
788 : * Internal subroutine to set up connection parameters given an already-
789 : * created PGconn and a conninfo string. Derived settings should be
790 : * processed by calling connectOptions2 next. (We split them because
791 : * PQsetdbLogin overrides defaults in between.)
792 : *
793 : * Returns true if OK, false if trouble (in which case errorMessage is set
794 : * and so is conn->status).
795 : */
796 : static bool
797 0 : connectOptions1(PGconn *conn, const char *conninfo)
798 : {
799 : PQconninfoOption *connOptions;
800 :
801 : /*
802 : * Parse the conninfo string
803 : */
804 0 : connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
805 0 : if (connOptions == NULL)
806 : {
807 0 : conn->status = CONNECTION_BAD;
808 : /* errorMessage is already set */
809 0 : return false;
810 : }
811 :
812 : /*
813 : * Move option values into conn structure
814 : */
815 0 : if (!fillPGconn(conn, connOptions))
816 : {
817 0 : conn->status = CONNECTION_BAD;
818 0 : PQconninfoFree(connOptions);
819 0 : return false;
820 : }
821 :
822 : /*
823 : * Free the option info - all is in conn now
824 : */
825 0 : PQconninfoFree(connOptions);
826 :
827 0 : return true;
828 : }
829 :
830 : /*
831 : * Count the number of elements in a simple comma-separated list.
832 : */
833 : static int
834 217 : count_comma_separated_elems(const char *input)
835 : {
836 : int n;
837 :
838 217 : n = 1;
839 4991 : for (; *input != '\0'; input++)
840 : {
841 4774 : if (*input == ',')
842 0 : n++;
843 : }
844 :
845 217 : return n;
846 : }
847 :
848 : /*
849 : * Parse a simple comma-separated list.
850 : *
851 : * On each call, returns a malloc'd copy of the next element, and sets *more
852 : * to indicate whether there are any more elements in the list after this,
853 : * and updates *startptr to point to the next element, if any.
854 : *
855 : * On out of memory, returns NULL.
856 : */
857 : static char *
858 434 : parse_comma_separated_list(char **startptr, bool *more)
859 : {
860 : char *p;
861 434 : char *s = *startptr;
862 : char *e;
863 : int len;
864 :
865 : /*
866 : * Search for the end of the current element; a comma or end-of-string
867 : * acts as a terminator.
868 : */
869 434 : e = s;
870 6727 : while (*e != '\0' && *e != ',')
871 5859 : ++e;
872 434 : *more = (*e == ',');
873 :
874 434 : len = e - s;
875 434 : p = (char *) malloc(sizeof(char) * (len + 1));
876 434 : if (p)
877 : {
878 434 : memcpy(p, s, len);
879 434 : p[len] = '\0';
880 : }
881 434 : *startptr = e + 1;
882 :
883 434 : return p;
884 : }
885 :
886 : /*
887 : * connectOptions2
888 : *
889 : * Compute derived connection options after absorbing all user-supplied info.
890 : *
891 : * Returns true if OK, false if trouble (in which case errorMessage is set
892 : * and so is conn->status).
893 : */
894 : static bool
895 217 : connectOptions2(PGconn *conn)
896 : {
897 : /*
898 : * Allocate memory for details about each host to which we might possibly
899 : * try to connect. For that, count the number of elements in the hostaddr
900 : * or host options. If neither is given, assume one host.
901 : */
902 217 : conn->whichhost = 0;
903 217 : if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
904 0 : conn->nconnhost = count_comma_separated_elems(conn->pghostaddr);
905 217 : else if (conn->pghost && conn->pghost[0] != '\0')
906 217 : conn->nconnhost = count_comma_separated_elems(conn->pghost);
907 : else
908 0 : conn->nconnhost = 1;
909 217 : conn->connhost = (pg_conn_host *)
910 217 : calloc(conn->nconnhost, sizeof(pg_conn_host));
911 217 : if (conn->connhost == NULL)
912 0 : goto oom_error;
913 :
914 : /*
915 : * We now have one pg_conn_host structure per possible host. Fill in the
916 : * host details for each one.
917 : */
918 217 : if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
919 : {
920 : int i;
921 0 : char *s = conn->pghostaddr;
922 0 : bool more = true;
923 :
924 0 : for (i = 0; i < conn->nconnhost && more; i++)
925 : {
926 0 : conn->connhost[i].hostaddr = parse_comma_separated_list(&s, &more);
927 0 : if (conn->connhost[i].hostaddr == NULL)
928 0 : goto oom_error;
929 :
930 0 : conn->connhost[i].type = CHT_HOST_ADDRESS;
931 : }
932 :
933 : /*
934 : * If hostaddr was given, the array was allocated according to the
935 : * number of elements in the hostaddr list, so it really should be the
936 : * right size.
937 : */
938 0 : Assert(!more);
939 0 : Assert(i == conn->nconnhost);
940 : }
941 :
942 217 : if (conn->pghost != NULL && conn->pghost[0] != '\0')
943 : {
944 : int i;
945 217 : char *s = conn->pghost;
946 217 : bool more = true;
947 :
948 434 : for (i = 0; i < conn->nconnhost && more; i++)
949 : {
950 217 : conn->connhost[i].host = parse_comma_separated_list(&s, &more);
951 217 : if (conn->connhost[i].host == NULL)
952 0 : goto oom_error;
953 :
954 : /* Identify the type of host. */
955 217 : if (conn->pghostaddr == NULL || conn->pghostaddr[0] == '\0')
956 : {
957 217 : conn->connhost[i].type = CHT_HOST_NAME;
958 : #ifdef HAVE_UNIX_SOCKETS
959 217 : if (is_absolute_path(conn->connhost[i].host))
960 217 : conn->connhost[i].type = CHT_UNIX_SOCKET;
961 : #endif
962 : }
963 : }
964 217 : if (more || i != conn->nconnhost)
965 : {
966 0 : conn->status = CONNECTION_BAD;
967 0 : printfPQExpBuffer(&conn->errorMessage,
968 : libpq_gettext("could not match %d host names to %d hostaddrs\n"),
969 0 : count_comma_separated_elems(conn->pghost), conn->nconnhost);
970 0 : return false;
971 : }
972 : }
973 :
974 : /*
975 : * If neither host or hostaddr options was given, connect to default host.
976 : */
977 434 : if ((conn->pghostaddr == NULL || conn->pghostaddr[0] == '\0') &&
978 434 : (conn->pghost == NULL || conn->pghost[0] == '\0'))
979 : {
980 0 : Assert(conn->nconnhost == 1);
981 : #ifdef HAVE_UNIX_SOCKETS
982 0 : conn->connhost[0].host = strdup(DEFAULT_PGSOCKET_DIR);
983 0 : conn->connhost[0].type = CHT_UNIX_SOCKET;
984 : #else
985 : conn->connhost[0].host = strdup(DefaultHost);
986 : conn->connhost[0].type = CHT_HOST_NAME;
987 : #endif
988 0 : if (conn->connhost[0].host == NULL)
989 0 : goto oom_error;
990 : }
991 :
992 : /*
993 : * Next, work out the port number corresponding to each host name.
994 : */
995 217 : if (conn->pgport != NULL && conn->pgport[0] != '\0')
996 : {
997 : int i;
998 217 : char *s = conn->pgport;
999 217 : bool more = true;
1000 :
1001 434 : for (i = 0; i < conn->nconnhost && more; i++)
1002 : {
1003 217 : conn->connhost[i].port = parse_comma_separated_list(&s, &more);
1004 217 : if (conn->connhost[i].port == NULL)
1005 0 : goto oom_error;
1006 : }
1007 :
1008 : /*
1009 : * If exactly one port was given, use it for every host. Otherwise,
1010 : * there must be exactly as many ports as there were hosts.
1011 : */
1012 434 : if (i == 1 && !more)
1013 : {
1014 217 : for (i = 1; i < conn->nconnhost; i++)
1015 : {
1016 0 : conn->connhost[i].port = strdup(conn->connhost[0].port);
1017 0 : if (conn->connhost[i].port == NULL)
1018 0 : goto oom_error;
1019 : }
1020 : }
1021 0 : else if (more || i != conn->nconnhost)
1022 : {
1023 0 : conn->status = CONNECTION_BAD;
1024 0 : printfPQExpBuffer(&conn->errorMessage,
1025 : libpq_gettext("could not match %d port numbers to %d hosts\n"),
1026 0 : count_comma_separated_elems(conn->pgport), conn->nconnhost);
1027 0 : return false;
1028 : }
1029 : }
1030 :
1031 : /*
1032 : * If user name was not given, fetch it. (Most likely, the fetch will
1033 : * fail, since the only way we get here is if pg_fe_getauthname() failed
1034 : * during conninfo_add_defaults(). But now we want an error message.)
1035 : */
1036 217 : if (conn->pguser == NULL || conn->pguser[0] == '\0')
1037 : {
1038 0 : if (conn->pguser)
1039 0 : free(conn->pguser);
1040 0 : conn->pguser = pg_fe_getauthname(&conn->errorMessage);
1041 0 : if (!conn->pguser)
1042 : {
1043 0 : conn->status = CONNECTION_BAD;
1044 0 : return false;
1045 : }
1046 : }
1047 :
1048 : /*
1049 : * If database name was not given, default it to equal user name
1050 : */
1051 217 : if (conn->dbName == NULL || conn->dbName[0] == '\0')
1052 : {
1053 0 : if (conn->dbName)
1054 0 : free(conn->dbName);
1055 0 : conn->dbName = strdup(conn->pguser);
1056 0 : if (!conn->dbName)
1057 0 : goto oom_error;
1058 : }
1059 :
1060 : /*
1061 : * Supply default password if none given. Note that the password might be
1062 : * different for each host/port pair.
1063 : */
1064 217 : if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1065 : {
1066 : int i;
1067 :
1068 217 : if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1069 : {
1070 : /* Identify password file to use; fail if we can't */
1071 : char homedir[MAXPGPATH];
1072 :
1073 217 : if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
1074 : {
1075 0 : conn->status = CONNECTION_BAD;
1076 0 : printfPQExpBuffer(&conn->errorMessage,
1077 : libpq_gettext("could not get home directory to locate password file\n"));
1078 0 : return false;
1079 : }
1080 :
1081 217 : if (conn->pgpassfile)
1082 0 : free(conn->pgpassfile);
1083 217 : conn->pgpassfile = malloc(MAXPGPATH);
1084 217 : if (!conn->pgpassfile)
1085 0 : goto oom_error;
1086 :
1087 217 : snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s", homedir, PGPASSFILE);
1088 : }
1089 :
1090 434 : for (i = 0; i < conn->nconnhost; i++)
1091 : {
1092 : /*
1093 : * Try to get a password for this host from pgpassfile. We use
1094 : * host name rather than host address in the same manner to
1095 : * PQhost().
1096 : */
1097 217 : char *pwhost = conn->connhost[i].host;
1098 :
1099 217 : if (conn->connhost[i].type == CHT_HOST_ADDRESS &&
1100 0 : conn->connhost[i].host != NULL && conn->connhost[i].host[0] != '\0')
1101 0 : pwhost = conn->connhost[i].hostaddr;
1102 :
1103 434 : conn->connhost[i].password =
1104 434 : passwordFromFile(pwhost,
1105 217 : conn->connhost[i].port,
1106 : conn->dbName,
1107 : conn->pguser,
1108 : conn->pgpassfile);
1109 : /* If we got one, set pgpassfile_used */
1110 217 : if (conn->connhost[i].password != NULL)
1111 0 : conn->pgpassfile_used = true;
1112 : }
1113 : }
1114 :
1115 : /*
1116 : * validate sslmode option
1117 : */
1118 217 : if (conn->sslmode)
1119 : {
1120 217 : if (strcmp(conn->sslmode, "disable") != 0
1121 0 : && strcmp(conn->sslmode, "allow") != 0
1122 0 : && strcmp(conn->sslmode, "prefer") != 0
1123 0 : && strcmp(conn->sslmode, "require") != 0
1124 0 : && strcmp(conn->sslmode, "verify-ca") != 0
1125 0 : && strcmp(conn->sslmode, "verify-full") != 0)
1126 : {
1127 0 : conn->status = CONNECTION_BAD;
1128 0 : printfPQExpBuffer(&conn->errorMessage,
1129 : libpq_gettext("invalid sslmode value: \"%s\"\n"),
1130 : conn->sslmode);
1131 0 : return false;
1132 : }
1133 :
1134 : #ifndef USE_SSL
1135 217 : switch (conn->sslmode[0])
1136 : {
1137 : case 'a': /* "allow" */
1138 : case 'p': /* "prefer" */
1139 :
1140 : /*
1141 : * warn user that an SSL connection will never be negotiated
1142 : * since SSL was not compiled in?
1143 : */
1144 0 : break;
1145 :
1146 : case 'r': /* "require" */
1147 : case 'v': /* "verify-ca" or "verify-full" */
1148 0 : conn->status = CONNECTION_BAD;
1149 0 : printfPQExpBuffer(&conn->errorMessage,
1150 : libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
1151 : conn->sslmode);
1152 0 : return false;
1153 : }
1154 : #endif
1155 : }
1156 : else
1157 : {
1158 0 : conn->sslmode = strdup(DefaultSSLMode);
1159 0 : if (!conn->sslmode)
1160 0 : goto oom_error;
1161 : }
1162 :
1163 : /*
1164 : * Resolve special "auto" client_encoding from the locale
1165 : */
1166 219 : if (conn->client_encoding_initial &&
1167 2 : strcmp(conn->client_encoding_initial, "auto") == 0)
1168 : {
1169 2 : free(conn->client_encoding_initial);
1170 2 : conn->client_encoding_initial = strdup(pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true)));
1171 2 : if (!conn->client_encoding_initial)
1172 0 : goto oom_error;
1173 : }
1174 :
1175 : /*
1176 : * Validate target_session_attrs option.
1177 : */
1178 217 : if (conn->target_session_attrs)
1179 : {
1180 217 : if (strcmp(conn->target_session_attrs, "any") != 0
1181 0 : && strcmp(conn->target_session_attrs, "read-write") != 0)
1182 : {
1183 0 : conn->status = CONNECTION_BAD;
1184 0 : printfPQExpBuffer(&conn->errorMessage,
1185 : libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
1186 : conn->target_session_attrs);
1187 0 : return false;
1188 : }
1189 : }
1190 :
1191 : /*
1192 : * Only if we get this far is it appropriate to try to connect. (We need a
1193 : * state flag, rather than just the boolean result of this function, in
1194 : * case someone tries to PQreset() the PGconn.)
1195 : */
1196 217 : conn->options_valid = true;
1197 :
1198 217 : return true;
1199 :
1200 : oom_error:
1201 0 : conn->status = CONNECTION_BAD;
1202 0 : printfPQExpBuffer(&conn->errorMessage,
1203 : libpq_gettext("out of memory\n"));
1204 0 : return false;
1205 : }
1206 :
1207 : /*
1208 : * PQconndefaults
1209 : *
1210 : * Construct a default connection options array, which identifies all the
1211 : * available options and shows any default values that are available from the
1212 : * environment etc. On error (eg out of memory), NULL is returned.
1213 : *
1214 : * Using this function, an application may determine all possible options
1215 : * and their current default values.
1216 : *
1217 : * NOTE: as of PostgreSQL 7.0, the returned array is dynamically allocated
1218 : * and should be freed when no longer needed via PQconninfoFree(). (In prior
1219 : * versions, the returned array was static, but that's not thread-safe.)
1220 : * Pre-7.0 applications that use this function will see a small memory leak
1221 : * until they are updated to call PQconninfoFree.
1222 : */
1223 : PQconninfoOption *
1224 0 : PQconndefaults(void)
1225 : {
1226 : PQExpBufferData errorBuf;
1227 : PQconninfoOption *connOptions;
1228 :
1229 : /* We don't actually report any errors here, but callees want a buffer */
1230 0 : initPQExpBuffer(&errorBuf);
1231 0 : if (PQExpBufferDataBroken(errorBuf))
1232 0 : return NULL; /* out of memory already :-( */
1233 :
1234 0 : connOptions = conninfo_init(&errorBuf);
1235 0 : if (connOptions != NULL)
1236 : {
1237 : /* pass NULL errorBuf to ignore errors */
1238 0 : if (!conninfo_add_defaults(connOptions, NULL))
1239 : {
1240 0 : PQconninfoFree(connOptions);
1241 0 : connOptions = NULL;
1242 : }
1243 : }
1244 :
1245 0 : termPQExpBuffer(&errorBuf);
1246 0 : return connOptions;
1247 : }
1248 :
1249 : /* ----------------
1250 : * PQsetdbLogin
1251 : *
1252 : * establishes a connection to a postgres backend through the postmaster
1253 : * at the specified host and port.
1254 : *
1255 : * returns a PGconn* which is needed for all subsequent libpq calls
1256 : *
1257 : * if the status field of the connection returned is CONNECTION_BAD,
1258 : * then only the errorMessage is likely to be useful.
1259 : * ----------------
1260 : */
1261 : PGconn *
1262 0 : PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
1263 : const char *pgtty, const char *dbName, const char *login,
1264 : const char *pwd)
1265 : {
1266 : PGconn *conn;
1267 :
1268 : /*
1269 : * Allocate memory for the conn structure
1270 : */
1271 0 : conn = makeEmptyPGconn();
1272 0 : if (conn == NULL)
1273 0 : return NULL;
1274 :
1275 : /*
1276 : * If the dbName parameter contains what looks like a connection string,
1277 : * parse it into conn struct using connectOptions1.
1278 : */
1279 0 : if (dbName && recognized_connection_string(dbName))
1280 : {
1281 0 : if (!connectOptions1(conn, dbName))
1282 0 : return conn;
1283 : }
1284 : else
1285 : {
1286 : /*
1287 : * Old-style path: first, parse an empty conninfo string in order to
1288 : * set up the same defaults that PQconnectdb() would use.
1289 : */
1290 0 : if (!connectOptions1(conn, ""))
1291 0 : return conn;
1292 :
1293 : /* Insert dbName parameter value into struct */
1294 0 : if (dbName && dbName[0] != '\0')
1295 : {
1296 0 : if (conn->dbName)
1297 0 : free(conn->dbName);
1298 0 : conn->dbName = strdup(dbName);
1299 0 : if (!conn->dbName)
1300 0 : goto oom_error;
1301 : }
1302 : }
1303 :
1304 : /*
1305 : * Insert remaining parameters into struct, overriding defaults (as well
1306 : * as any conflicting data from dbName taken as a conninfo).
1307 : */
1308 0 : if (pghost && pghost[0] != '\0')
1309 : {
1310 0 : if (conn->pghost)
1311 0 : free(conn->pghost);
1312 0 : conn->pghost = strdup(pghost);
1313 0 : if (!conn->pghost)
1314 0 : goto oom_error;
1315 : }
1316 :
1317 0 : if (pgport && pgport[0] != '\0')
1318 : {
1319 0 : if (conn->pgport)
1320 0 : free(conn->pgport);
1321 0 : conn->pgport = strdup(pgport);
1322 0 : if (!conn->pgport)
1323 0 : goto oom_error;
1324 : }
1325 :
1326 0 : if (pgoptions && pgoptions[0] != '\0')
1327 : {
1328 0 : if (conn->pgoptions)
1329 0 : free(conn->pgoptions);
1330 0 : conn->pgoptions = strdup(pgoptions);
1331 0 : if (!conn->pgoptions)
1332 0 : goto oom_error;
1333 : }
1334 :
1335 0 : if (pgtty && pgtty[0] != '\0')
1336 : {
1337 0 : if (conn->pgtty)
1338 0 : free(conn->pgtty);
1339 0 : conn->pgtty = strdup(pgtty);
1340 0 : if (!conn->pgtty)
1341 0 : goto oom_error;
1342 : }
1343 :
1344 0 : if (login && login[0] != '\0')
1345 : {
1346 0 : if (conn->pguser)
1347 0 : free(conn->pguser);
1348 0 : conn->pguser = strdup(login);
1349 0 : if (!conn->pguser)
1350 0 : goto oom_error;
1351 : }
1352 :
1353 0 : if (pwd && pwd[0] != '\0')
1354 : {
1355 0 : if (conn->pgpass)
1356 0 : free(conn->pgpass);
1357 0 : conn->pgpass = strdup(pwd);
1358 0 : if (!conn->pgpass)
1359 0 : goto oom_error;
1360 : }
1361 :
1362 : /*
1363 : * Compute derived options
1364 : */
1365 0 : if (!connectOptions2(conn))
1366 0 : return conn;
1367 :
1368 : /*
1369 : * Connect to the database
1370 : */
1371 0 : if (connectDBStart(conn))
1372 0 : (void) connectDBComplete(conn);
1373 :
1374 0 : return conn;
1375 :
1376 : oom_error:
1377 0 : conn->status = CONNECTION_BAD;
1378 0 : printfPQExpBuffer(&conn->errorMessage,
1379 : libpq_gettext("out of memory\n"));
1380 0 : return conn;
1381 : }
1382 :
1383 :
1384 : /* ----------
1385 : * connectNoDelay -
1386 : * Sets the TCP_NODELAY socket option.
1387 : * Returns 1 if successful, 0 if not.
1388 : * ----------
1389 : */
1390 : static int
1391 0 : connectNoDelay(PGconn *conn)
1392 : {
1393 : #ifdef TCP_NODELAY
1394 0 : int on = 1;
1395 :
1396 0 : if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1397 : (char *) &on,
1398 : sizeof(on)) < 0)
1399 : {
1400 : char sebuf[256];
1401 :
1402 0 : appendPQExpBuffer(&conn->errorMessage,
1403 : libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
1404 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1405 0 : return 0;
1406 : }
1407 : #endif
1408 :
1409 0 : return 1;
1410 : }
1411 :
1412 :
1413 : /* ----------
1414 : * connectFailureMessage -
1415 : * create a friendly error message on connection failure.
1416 : * ----------
1417 : */
1418 : static void
1419 2 : connectFailureMessage(PGconn *conn, int errorno)
1420 : {
1421 : char sebuf[256];
1422 :
1423 : #ifdef HAVE_UNIX_SOCKETS
1424 2 : if (IS_AF_UNIX(conn->raddr.addr.ss_family))
1425 : {
1426 : char service[NI_MAXHOST];
1427 :
1428 2 : pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
1429 : NULL, 0,
1430 : service, sizeof(service),
1431 : NI_NUMERICSERV);
1432 2 : appendPQExpBuffer(&conn->errorMessage,
1433 : libpq_gettext("could not connect to server: %s\n"
1434 : "\tIs the server running locally and accepting\n"
1435 : "\tconnections on Unix domain socket \"%s\"?\n"),
1436 : SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1437 : service);
1438 : }
1439 : else
1440 : #endif /* HAVE_UNIX_SOCKETS */
1441 : {
1442 : char host_addr[NI_MAXHOST];
1443 : const char *displayed_host;
1444 : const char *displayed_port;
1445 0 : struct sockaddr_storage *addr = &conn->raddr.addr;
1446 :
1447 : /*
1448 : * Optionally display the network address with the hostname. This is
1449 : * useful to distinguish between IPv4 and IPv6 connections.
1450 : */
1451 0 : if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
1452 0 : strlcpy(host_addr, conn->connhost[conn->whichhost].hostaddr, NI_MAXHOST);
1453 0 : else if (addr->ss_family == AF_INET)
1454 : {
1455 0 : if (inet_net_ntop(AF_INET,
1456 0 : &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1457 : 32,
1458 : host_addr, sizeof(host_addr)) == NULL)
1459 0 : strcpy(host_addr, "???");
1460 : }
1461 : #ifdef HAVE_IPV6
1462 0 : else if (addr->ss_family == AF_INET6)
1463 : {
1464 0 : if (inet_net_ntop(AF_INET6,
1465 0 : &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1466 : 128,
1467 : host_addr, sizeof(host_addr)) == NULL)
1468 0 : strcpy(host_addr, "???");
1469 : }
1470 : #endif
1471 : else
1472 0 : strcpy(host_addr, "???");
1473 :
1474 : /* To which host and port were we actually connecting? */
1475 0 : if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
1476 0 : displayed_host = conn->connhost[conn->whichhost].hostaddr;
1477 : else
1478 0 : displayed_host = conn->connhost[conn->whichhost].host;
1479 0 : displayed_port = conn->connhost[conn->whichhost].port;
1480 0 : if (displayed_port == NULL || displayed_port[0] == '\0')
1481 0 : displayed_port = DEF_PGPORT_STR;
1482 :
1483 : /*
1484 : * If the user did not supply an IP address using 'hostaddr', and
1485 : * 'host' was missing or does not match our lookup, display the
1486 : * looked-up IP address.
1487 : */
1488 0 : if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS &&
1489 0 : strcmp(displayed_host, host_addr) != 0)
1490 0 : appendPQExpBuffer(&conn->errorMessage,
1491 : libpq_gettext("could not connect to server: %s\n"
1492 : "\tIs the server running on host \"%s\" (%s) and accepting\n"
1493 : "\tTCP/IP connections on port %s?\n"),
1494 : SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1495 : displayed_host,
1496 : host_addr,
1497 : displayed_port);
1498 : else
1499 0 : appendPQExpBuffer(&conn->errorMessage,
1500 : libpq_gettext("could not connect to server: %s\n"
1501 : "\tIs the server running on host \"%s\" and accepting\n"
1502 : "\tTCP/IP connections on port %s?\n"),
1503 : SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1504 : displayed_host,
1505 : displayed_port);
1506 : }
1507 2 : }
1508 :
1509 : /*
1510 : * Should we use keepalives? Returns 1 if yes, 0 if no, and -1 if
1511 : * conn->keepalives is set to a value which is not parseable as an
1512 : * integer.
1513 : */
1514 : static int
1515 0 : useKeepalives(PGconn *conn)
1516 : {
1517 : char *ep;
1518 : int val;
1519 :
1520 0 : if (conn->keepalives == NULL)
1521 0 : return 1;
1522 0 : val = strtol(conn->keepalives, &ep, 10);
1523 0 : if (*ep)
1524 0 : return -1;
1525 0 : return val != 0 ? 1 : 0;
1526 : }
1527 :
1528 : #ifndef WIN32
1529 : /*
1530 : * Set the keepalive idle timer.
1531 : */
1532 : static int
1533 0 : setKeepalivesIdle(PGconn *conn)
1534 : {
1535 : int idle;
1536 :
1537 0 : if (conn->keepalives_idle == NULL)
1538 0 : return 1;
1539 :
1540 0 : idle = atoi(conn->keepalives_idle);
1541 0 : if (idle < 0)
1542 0 : idle = 0;
1543 :
1544 : #ifdef PG_TCP_KEEPALIVE_IDLE
1545 0 : if (setsockopt(conn->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
1546 : (char *) &idle, sizeof(idle)) < 0)
1547 : {
1548 : char sebuf[256];
1549 :
1550 0 : appendPQExpBuffer(&conn->errorMessage,
1551 : libpq_gettext("setsockopt(%s) failed: %s\n"),
1552 : PG_TCP_KEEPALIVE_IDLE_STR,
1553 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1554 0 : return 0;
1555 : }
1556 : #endif
1557 :
1558 0 : return 1;
1559 : }
1560 :
1561 : /*
1562 : * Set the keepalive interval.
1563 : */
1564 : static int
1565 0 : setKeepalivesInterval(PGconn *conn)
1566 : {
1567 : int interval;
1568 :
1569 0 : if (conn->keepalives_interval == NULL)
1570 0 : return 1;
1571 :
1572 0 : interval = atoi(conn->keepalives_interval);
1573 0 : if (interval < 0)
1574 0 : interval = 0;
1575 :
1576 : #ifdef TCP_KEEPINTVL
1577 0 : if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPINTVL,
1578 : (char *) &interval, sizeof(interval)) < 0)
1579 : {
1580 : char sebuf[256];
1581 :
1582 0 : appendPQExpBuffer(&conn->errorMessage,
1583 : libpq_gettext("setsockopt(%s) failed: %s\n"),
1584 : "TCP_KEEPINTVL",
1585 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1586 0 : return 0;
1587 : }
1588 : #endif
1589 :
1590 0 : return 1;
1591 : }
1592 :
1593 : /*
1594 : * Set the count of lost keepalive packets that will trigger a connection
1595 : * break.
1596 : */
1597 : static int
1598 0 : setKeepalivesCount(PGconn *conn)
1599 : {
1600 : int count;
1601 :
1602 0 : if (conn->keepalives_count == NULL)
1603 0 : return 1;
1604 :
1605 0 : count = atoi(conn->keepalives_count);
1606 0 : if (count < 0)
1607 0 : count = 0;
1608 :
1609 : #ifdef TCP_KEEPCNT
1610 0 : if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPCNT,
1611 : (char *) &count, sizeof(count)) < 0)
1612 : {
1613 : char sebuf[256];
1614 :
1615 0 : appendPQExpBuffer(&conn->errorMessage,
1616 : libpq_gettext("setsockopt(%s) failed: %s\n"),
1617 : "TCP_KEEPCNT",
1618 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1619 0 : return 0;
1620 : }
1621 : #endif
1622 :
1623 0 : return 1;
1624 : }
1625 : #else /* WIN32 */
1626 : #ifdef SIO_KEEPALIVE_VALS
1627 : /*
1628 : * Enable keepalives and set the keepalive values on Win32,
1629 : * where they are always set in one batch.
1630 : */
1631 : static int
1632 : setKeepalivesWin32(PGconn *conn)
1633 : {
1634 : struct tcp_keepalive ka;
1635 : DWORD retsize;
1636 : int idle = 0;
1637 : int interval = 0;
1638 :
1639 : if (conn->keepalives_idle)
1640 : idle = atoi(conn->keepalives_idle);
1641 : if (idle <= 0)
1642 : idle = 2 * 60 * 60; /* 2 hours = default */
1643 :
1644 : if (conn->keepalives_interval)
1645 : interval = atoi(conn->keepalives_interval);
1646 : if (interval <= 0)
1647 : interval = 1; /* 1 second = default */
1648 :
1649 : ka.onoff = 1;
1650 : ka.keepalivetime = idle * 1000;
1651 : ka.keepaliveinterval = interval * 1000;
1652 :
1653 : if (WSAIoctl(conn->sock,
1654 : SIO_KEEPALIVE_VALS,
1655 : (LPVOID) &ka,
1656 : sizeof(ka),
1657 : NULL,
1658 : 0,
1659 : &retsize,
1660 : NULL,
1661 : NULL)
1662 : != 0)
1663 : {
1664 : appendPQExpBuffer(&conn->errorMessage,
1665 : libpq_gettext("WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n"),
1666 : WSAGetLastError());
1667 : return 0;
1668 : }
1669 : return 1;
1670 : }
1671 : #endif /* SIO_KEEPALIVE_VALS */
1672 : #endif /* WIN32 */
1673 :
1674 : /* ----------
1675 : * connectDBStart -
1676 : * Begin the process of making a connection to the backend.
1677 : *
1678 : * Returns 1 if successful, 0 if not.
1679 : * ----------
1680 : */
1681 : static int
1682 217 : connectDBStart(PGconn *conn)
1683 : {
1684 : char portstr[MAXPGPATH];
1685 : int ret;
1686 : int i;
1687 :
1688 217 : if (!conn)
1689 0 : return 0;
1690 :
1691 217 : if (!conn->options_valid)
1692 0 : goto connect_errReturn;
1693 :
1694 : /* Ensure our buffers are empty */
1695 217 : conn->inStart = conn->inCursor = conn->inEnd = 0;
1696 217 : conn->outCount = 0;
1697 :
1698 : /*
1699 : * Look up socket addresses for each possible host using
1700 : * pg_getaddrinfo_all.
1701 : */
1702 868 : for (i = 0; i < conn->nconnhost; ++i)
1703 : {
1704 217 : pg_conn_host *ch = &conn->connhost[i];
1705 : struct addrinfo hint;
1706 : int thisport;
1707 :
1708 : /* Initialize hint structure */
1709 217 : MemSet(&hint, 0, sizeof(hint));
1710 217 : hint.ai_socktype = SOCK_STREAM;
1711 217 : hint.ai_family = AF_UNSPEC;
1712 :
1713 : /* Figure out the port number we're going to use. */
1714 217 : if (ch->port == NULL || ch->port[0] == '\0')
1715 0 : thisport = DEF_PGPORT;
1716 : else
1717 : {
1718 217 : thisport = atoi(ch->port);
1719 217 : if (thisport < 1 || thisport > 65535)
1720 : {
1721 0 : appendPQExpBuffer(&conn->errorMessage,
1722 : libpq_gettext("invalid port number: \"%s\"\n"),
1723 : ch->port);
1724 0 : conn->options_valid = false;
1725 0 : goto connect_errReturn;
1726 : }
1727 : }
1728 217 : snprintf(portstr, sizeof(portstr), "%d", thisport);
1729 :
1730 : /* Use pg_getaddrinfo_all() to resolve the address */
1731 217 : ret = 1;
1732 217 : switch (ch->type)
1733 : {
1734 : case CHT_HOST_NAME:
1735 0 : ret = pg_getaddrinfo_all(ch->host, portstr, &hint, &ch->addrlist);
1736 0 : if (ret || !ch->addrlist)
1737 0 : appendPQExpBuffer(&conn->errorMessage,
1738 : libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
1739 : ch->host, gai_strerror(ret));
1740 0 : break;
1741 :
1742 : case CHT_HOST_ADDRESS:
1743 0 : hint.ai_flags = AI_NUMERICHOST;
1744 0 : ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint, &ch->addrlist);
1745 0 : if (ret || !ch->addrlist)
1746 0 : appendPQExpBuffer(&conn->errorMessage,
1747 : libpq_gettext("could not parse network address \"%s\": %s\n"),
1748 : ch->host, gai_strerror(ret));
1749 0 : break;
1750 :
1751 : case CHT_UNIX_SOCKET:
1752 : #ifdef HAVE_UNIX_SOCKETS
1753 217 : hint.ai_family = AF_UNIX;
1754 217 : UNIXSOCK_PATH(portstr, thisport, ch->host);
1755 217 : if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
1756 : {
1757 0 : appendPQExpBuffer(&conn->errorMessage,
1758 : libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
1759 : portstr,
1760 : (int) (UNIXSOCK_PATH_BUFLEN - 1));
1761 0 : conn->options_valid = false;
1762 0 : goto connect_errReturn;
1763 : }
1764 :
1765 : /*
1766 : * NULL hostname tells pg_getaddrinfo_all to parse the service
1767 : * name as a Unix-domain socket path.
1768 : */
1769 217 : ret = pg_getaddrinfo_all(NULL, portstr, &hint, &ch->addrlist);
1770 217 : if (ret || !ch->addrlist)
1771 0 : appendPQExpBuffer(&conn->errorMessage,
1772 : libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
1773 : portstr, gai_strerror(ret));
1774 217 : break;
1775 : #else
1776 : Assert(false);
1777 : conn->options_valid = false;
1778 : goto connect_errReturn;
1779 : #endif
1780 : }
1781 217 : if (ret || !ch->addrlist)
1782 : {
1783 0 : if (ch->addrlist)
1784 : {
1785 0 : pg_freeaddrinfo_all(hint.ai_family, ch->addrlist);
1786 0 : ch->addrlist = NULL;
1787 : }
1788 0 : conn->options_valid = false;
1789 0 : goto connect_errReturn;
1790 : }
1791 : }
1792 :
1793 : #ifdef USE_SSL
1794 : /* setup values based on SSL mode */
1795 : if (conn->sslmode[0] == 'd') /* "disable" */
1796 : conn->allow_ssl_try = false;
1797 : else if (conn->sslmode[0] == 'a') /* "allow" */
1798 : conn->wait_ssl_try = true;
1799 : #endif
1800 :
1801 : /*
1802 : * Set up to try to connect, with protocol 3.0 as the first attempt.
1803 : */
1804 217 : conn->whichhost = 0;
1805 217 : conn->addr_cur = conn->connhost[0].addrlist;
1806 217 : conn->pversion = PG_PROTOCOL(3, 0);
1807 217 : conn->send_appname = true;
1808 217 : conn->status = CONNECTION_NEEDED;
1809 :
1810 : /*
1811 : * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
1812 : * so that it can easily be re-executed if needed again during the
1813 : * asynchronous startup process. However, we must run it once here,
1814 : * because callers expect a success return from this routine to mean that
1815 : * we are in PGRES_POLLING_WRITING connection state.
1816 : */
1817 217 : if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
1818 215 : return 1;
1819 :
1820 : connect_errReturn:
1821 2 : pqDropConnection(conn, true);
1822 2 : conn->status = CONNECTION_BAD;
1823 2 : return 0;
1824 : }
1825 :
1826 :
1827 : /*
1828 : * connectDBComplete
1829 : *
1830 : * Block and complete a connection.
1831 : *
1832 : * Returns 1 on success, 0 on failure.
1833 : */
1834 : static int
1835 215 : connectDBComplete(PGconn *conn)
1836 : {
1837 215 : PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
1838 215 : time_t finish_time = ((time_t) -1);
1839 215 : int timeout = 0;
1840 :
1841 215 : if (conn == NULL || conn->status == CONNECTION_BAD)
1842 0 : return 0;
1843 :
1844 : /*
1845 : * Set up a time limit, if connect_timeout isn't zero.
1846 : */
1847 215 : if (conn->connect_timeout != NULL)
1848 : {
1849 0 : timeout = atoi(conn->connect_timeout);
1850 0 : if (timeout > 0)
1851 : {
1852 : /*
1853 : * Rounding could cause connection to fail; need at least 2 secs
1854 : */
1855 0 : if (timeout < 2)
1856 0 : timeout = 2;
1857 : /* calculate the finish time based on start + timeout */
1858 0 : finish_time = time(NULL) + timeout;
1859 : }
1860 : }
1861 :
1862 : for (;;)
1863 : {
1864 645 : int ret = 0;
1865 :
1866 : /*
1867 : * Wait, if necessary. Note that the initial state (just after
1868 : * PQconnectStart) is to wait for the socket to select for writing.
1869 : */
1870 645 : switch (flag)
1871 : {
1872 : case PGRES_POLLING_OK:
1873 :
1874 : /*
1875 : * Reset stored error messages since we now have a working
1876 : * connection
1877 : */
1878 215 : resetPQExpBuffer(&conn->errorMessage);
1879 215 : return 1; /* success! */
1880 :
1881 : case PGRES_POLLING_READING:
1882 215 : ret = pqWaitTimed(1, 0, conn, finish_time);
1883 215 : if (ret == -1)
1884 : {
1885 0 : conn->status = CONNECTION_BAD;
1886 0 : return 0;
1887 : }
1888 215 : break;
1889 :
1890 : case PGRES_POLLING_WRITING:
1891 215 : ret = pqWaitTimed(0, 1, conn, finish_time);
1892 215 : if (ret == -1)
1893 : {
1894 0 : conn->status = CONNECTION_BAD;
1895 0 : return 0;
1896 : }
1897 215 : break;
1898 :
1899 : default:
1900 : /* Just in case we failed to set it in PQconnectPoll */
1901 0 : conn->status = CONNECTION_BAD;
1902 0 : return 0;
1903 : }
1904 :
1905 430 : if (ret == 1) /* connect_timeout elapsed */
1906 : {
1907 : /*
1908 : * If there are no more hosts, return (the error message is
1909 : * already set)
1910 : */
1911 0 : if (++conn->whichhost >= conn->nconnhost)
1912 : {
1913 0 : conn->whichhost = 0;
1914 0 : conn->status = CONNECTION_BAD;
1915 0 : return 0;
1916 : }
1917 :
1918 : /*
1919 : * Attempt connection to the next host, starting the
1920 : * connect_timeout timer
1921 : */
1922 0 : pqDropConnection(conn, true);
1923 0 : conn->addr_cur = conn->connhost[conn->whichhost].addrlist;
1924 0 : conn->status = CONNECTION_NEEDED;
1925 0 : if (conn->connect_timeout != NULL)
1926 0 : finish_time = time(NULL) + timeout;
1927 : }
1928 :
1929 : /*
1930 : * Now try to advance the state machine.
1931 : */
1932 430 : flag = PQconnectPoll(conn);
1933 430 : }
1934 : }
1935 :
1936 : /*
1937 : * This subroutine saves conn->errorMessage, which will be restored back by
1938 : * restoreErrorMessage subroutine.
1939 : */
1940 : static bool
1941 0 : saveErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
1942 : {
1943 0 : initPQExpBuffer(savedMessage);
1944 0 : if (PQExpBufferBroken(savedMessage))
1945 : {
1946 0 : printfPQExpBuffer(&conn->errorMessage,
1947 : libpq_gettext("out of memory\n"));
1948 0 : return false;
1949 : }
1950 :
1951 0 : appendPQExpBufferStr(savedMessage,
1952 0 : conn->errorMessage.data);
1953 0 : resetPQExpBuffer(&conn->errorMessage);
1954 0 : return true;
1955 : }
1956 :
1957 : /*
1958 : * Restores saved error messages back to conn->errorMessage.
1959 : */
1960 : static void
1961 0 : restoreErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
1962 : {
1963 0 : appendPQExpBufferStr(savedMessage, conn->errorMessage.data);
1964 0 : resetPQExpBuffer(&conn->errorMessage);
1965 0 : appendPQExpBufferStr(&conn->errorMessage, savedMessage->data);
1966 0 : termPQExpBuffer(savedMessage);
1967 0 : }
1968 :
1969 : /* ----------------
1970 : * PQconnectPoll
1971 : *
1972 : * Poll an asynchronous connection.
1973 : *
1974 : * Returns a PostgresPollingStatusType.
1975 : * Before calling this function, use select(2) to determine when data
1976 : * has arrived..
1977 : *
1978 : * You must call PQfinish whether or not this fails.
1979 : *
1980 : * This function and PQconnectStart are intended to allow connections to be
1981 : * made without blocking the execution of your program on remote I/O. However,
1982 : * there are a number of caveats:
1983 : *
1984 : * o If you call PQtrace, ensure that the stream object into which you trace
1985 : * will not block.
1986 : * o If you do not supply an IP address for the remote host (i.e. you
1987 : * supply a host name instead) then PQconnectStart will block on
1988 : * gethostbyname. You will be fine if using Unix sockets (i.e. by
1989 : * supplying neither a host name nor a host address).
1990 : * o If your backend wants to use Kerberos authentication then you must
1991 : * supply both a host name and a host address, otherwise this function
1992 : * may block on gethostname.
1993 : *
1994 : * ----------------
1995 : */
1996 : PostgresPollingStatusType
1997 647 : PQconnectPoll(PGconn *conn)
1998 : {
1999 : PGresult *res;
2000 : char sebuf[256];
2001 : int optval;
2002 : PQExpBufferData savedMessage;
2003 :
2004 647 : if (conn == NULL)
2005 0 : return PGRES_POLLING_FAILED;
2006 :
2007 : /* Get the new data */
2008 647 : switch (conn->status)
2009 : {
2010 : /*
2011 : * We really shouldn't have been polled in these two cases, but we
2012 : * can handle it.
2013 : */
2014 : case CONNECTION_BAD:
2015 0 : return PGRES_POLLING_FAILED;
2016 : case CONNECTION_OK:
2017 0 : return PGRES_POLLING_OK;
2018 :
2019 : /* These are reading states */
2020 : case CONNECTION_AWAITING_RESPONSE:
2021 : case CONNECTION_AUTH_OK:
2022 : {
2023 : /* Load waiting data */
2024 215 : int n = pqReadData(conn);
2025 :
2026 215 : if (n < 0)
2027 0 : goto error_return;
2028 215 : if (n == 0)
2029 0 : return PGRES_POLLING_READING;
2030 :
2031 215 : break;
2032 : }
2033 :
2034 : /* These are writing states, so we just proceed. */
2035 : case CONNECTION_STARTED:
2036 : case CONNECTION_MADE:
2037 215 : break;
2038 :
2039 : /* We allow pqSetenvPoll to decide whether to proceed. */
2040 : case CONNECTION_SETENV:
2041 0 : break;
2042 :
2043 : /* Special cases: proceed without waiting. */
2044 : case CONNECTION_SSL_STARTUP:
2045 : case CONNECTION_NEEDED:
2046 : case CONNECTION_CHECK_WRITABLE:
2047 : case CONNECTION_CONSUME:
2048 217 : break;
2049 :
2050 : default:
2051 0 : appendPQExpBufferStr(&conn->errorMessage,
2052 : libpq_gettext(
2053 : "invalid connection state, "
2054 : "probably indicative of memory corruption\n"
2055 : ));
2056 0 : goto error_return;
2057 : }
2058 :
2059 :
2060 : keep_going: /* We will come back to here until there is
2061 : * nothing left to do. */
2062 1077 : switch (conn->status)
2063 : {
2064 : case CONNECTION_NEEDED:
2065 : {
2066 : /*
2067 : * Try to initiate a connection to one of the addresses
2068 : * returned by pg_getaddrinfo_all(). conn->addr_cur is the
2069 : * next one to try. We fail when we run out of addresses.
2070 : */
2071 : for (;;)
2072 : {
2073 : struct addrinfo *addr_cur;
2074 :
2075 : /*
2076 : * Advance to next possible host, if we've tried all of
2077 : * the addresses for the current host.
2078 : */
2079 219 : if (conn->addr_cur == NULL)
2080 : {
2081 2 : if (++conn->whichhost >= conn->nconnhost)
2082 : {
2083 2 : conn->whichhost = 0;
2084 2 : break;
2085 : }
2086 0 : conn->addr_cur =
2087 0 : conn->connhost[conn->whichhost].addrlist;
2088 : }
2089 :
2090 : /* Remember current address for possible error msg */
2091 217 : addr_cur = conn->addr_cur;
2092 217 : memcpy(&conn->raddr.addr, addr_cur->ai_addr,
2093 : addr_cur->ai_addrlen);
2094 217 : conn->raddr.salen = addr_cur->ai_addrlen;
2095 :
2096 217 : conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
2097 217 : if (conn->sock == PGINVALID_SOCKET)
2098 : {
2099 : /*
2100 : * ignore socket() failure if we have more addresses
2101 : * to try
2102 : */
2103 0 : if (addr_cur->ai_next != NULL ||
2104 0 : conn->whichhost + 1 < conn->nconnhost)
2105 : {
2106 0 : conn->addr_cur = addr_cur->ai_next;
2107 0 : continue;
2108 : }
2109 0 : appendPQExpBuffer(&conn->errorMessage,
2110 : libpq_gettext("could not create socket: %s\n"),
2111 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2112 0 : break;
2113 : }
2114 :
2115 : /*
2116 : * Select socket options: no delay of outgoing data for
2117 : * TCP sockets, nonblock mode, close-on-exec. Fail if any
2118 : * of this fails.
2119 : */
2120 217 : if (!IS_AF_UNIX(addr_cur->ai_family))
2121 : {
2122 0 : if (!connectNoDelay(conn))
2123 : {
2124 0 : pqDropConnection(conn, true);
2125 0 : conn->addr_cur = addr_cur->ai_next;
2126 0 : continue;
2127 : }
2128 : }
2129 217 : if (!pg_set_noblock(conn->sock))
2130 : {
2131 0 : appendPQExpBuffer(&conn->errorMessage,
2132 : libpq_gettext("could not set socket to nonblocking mode: %s\n"),
2133 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2134 0 : pqDropConnection(conn, true);
2135 0 : conn->addr_cur = addr_cur->ai_next;
2136 0 : continue;
2137 : }
2138 :
2139 : #ifdef F_SETFD
2140 217 : if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
2141 : {
2142 0 : appendPQExpBuffer(&conn->errorMessage,
2143 : libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
2144 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2145 0 : pqDropConnection(conn, true);
2146 0 : conn->addr_cur = addr_cur->ai_next;
2147 0 : continue;
2148 : }
2149 : #endif /* F_SETFD */
2150 :
2151 217 : if (!IS_AF_UNIX(addr_cur->ai_family))
2152 : {
2153 : #ifndef WIN32
2154 0 : int on = 1;
2155 : #endif
2156 0 : int usekeepalives = useKeepalives(conn);
2157 0 : int err = 0;
2158 :
2159 0 : if (usekeepalives < 0)
2160 : {
2161 0 : appendPQExpBufferStr(&conn->errorMessage,
2162 : libpq_gettext("keepalives parameter must be an integer\n"));
2163 0 : err = 1;
2164 : }
2165 0 : else if (usekeepalives == 0)
2166 : {
2167 : /* Do nothing */
2168 : }
2169 : #ifndef WIN32
2170 0 : else if (setsockopt(conn->sock,
2171 : SOL_SOCKET, SO_KEEPALIVE,
2172 : (char *) &on, sizeof(on)) < 0)
2173 : {
2174 0 : appendPQExpBuffer(&conn->errorMessage,
2175 : libpq_gettext("setsockopt(%s) failed: %s\n"),
2176 : "SO_KEEPALIVE",
2177 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2178 0 : err = 1;
2179 : }
2180 0 : else if (!setKeepalivesIdle(conn)
2181 0 : || !setKeepalivesInterval(conn)
2182 0 : || !setKeepalivesCount(conn))
2183 0 : err = 1;
2184 : #else /* WIN32 */
2185 : #ifdef SIO_KEEPALIVE_VALS
2186 : else if (!setKeepalivesWin32(conn))
2187 : err = 1;
2188 : #endif /* SIO_KEEPALIVE_VALS */
2189 : #endif /* WIN32 */
2190 :
2191 0 : if (err)
2192 : {
2193 0 : pqDropConnection(conn, true);
2194 0 : conn->addr_cur = addr_cur->ai_next;
2195 0 : continue;
2196 : }
2197 : }
2198 :
2199 : /*----------
2200 : * We have three methods of blocking SIGPIPE during
2201 : * send() calls to this socket:
2202 : *
2203 : * - setsockopt(sock, SO_NOSIGPIPE)
2204 : * - send(sock, ..., MSG_NOSIGNAL)
2205 : * - setting the signal mask to SIG_IGN during send()
2206 : *
2207 : * The third method requires three syscalls per send,
2208 : * so we prefer either of the first two, but they are
2209 : * less portable. The state is tracked in the following
2210 : * members of PGconn:
2211 : *
2212 : * conn->sigpipe_so - we have set up SO_NOSIGPIPE
2213 : * conn->sigpipe_flag - we're specifying MSG_NOSIGNAL
2214 : *
2215 : * If we can use SO_NOSIGPIPE, then set sigpipe_so here
2216 : * and we're done. Otherwise, set sigpipe_flag so that
2217 : * we will try MSG_NOSIGNAL on sends. If we get an error
2218 : * with MSG_NOSIGNAL, we'll clear that flag and revert to
2219 : * signal masking.
2220 : *----------
2221 : */
2222 217 : conn->sigpipe_so = false;
2223 : #ifdef MSG_NOSIGNAL
2224 217 : conn->sigpipe_flag = true;
2225 : #else
2226 : conn->sigpipe_flag = false;
2227 : #endif /* MSG_NOSIGNAL */
2228 :
2229 : #ifdef SO_NOSIGPIPE
2230 : optval = 1;
2231 : if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
2232 : (char *) &optval, sizeof(optval)) == 0)
2233 : {
2234 : conn->sigpipe_so = true;
2235 : conn->sigpipe_flag = false;
2236 : }
2237 : #endif /* SO_NOSIGPIPE */
2238 :
2239 : /*
2240 : * Start/make connection. This should not block, since we
2241 : * are in nonblock mode. If it does, well, too bad.
2242 : */
2243 217 : if (connect(conn->sock, addr_cur->ai_addr,
2244 : addr_cur->ai_addrlen) < 0)
2245 : {
2246 4 : if (SOCK_ERRNO == EINPROGRESS ||
2247 : #ifdef WIN32
2248 : SOCK_ERRNO == EWOULDBLOCK ||
2249 : #endif
2250 2 : SOCK_ERRNO == EINTR)
2251 : {
2252 : /*
2253 : * This is fine - we're in non-blocking mode, and
2254 : * the connection is in progress. Tell caller to
2255 : * wait for write-ready on socket.
2256 : */
2257 0 : conn->status = CONNECTION_STARTED;
2258 0 : return PGRES_POLLING_WRITING;
2259 : }
2260 : /* otherwise, trouble */
2261 : }
2262 : else
2263 : {
2264 : /*
2265 : * Hm, we're connected already --- seems the "nonblock
2266 : * connection" wasn't. Advance the state machine and
2267 : * go do the next stuff.
2268 : */
2269 215 : conn->status = CONNECTION_STARTED;
2270 215 : goto keep_going;
2271 : }
2272 :
2273 : /*
2274 : * This connection failed --- set up error report, then
2275 : * close socket (do it this way in case close() affects
2276 : * the value of errno...). We will ignore the connect()
2277 : * failure and keep going if there are more addresses.
2278 : */
2279 2 : connectFailureMessage(conn, SOCK_ERRNO);
2280 2 : pqDropConnection(conn, true);
2281 :
2282 : /*
2283 : * Try the next address, if any.
2284 : */
2285 2 : conn->addr_cur = addr_cur->ai_next;
2286 2 : } /* loop over addresses */
2287 :
2288 : /*
2289 : * Oops, no more addresses. An appropriate error message is
2290 : * already set up, so just set the right status.
2291 : */
2292 2 : goto error_return;
2293 : }
2294 :
2295 : case CONNECTION_STARTED:
2296 : {
2297 215 : ACCEPT_TYPE_ARG3 optlen = sizeof(optval);
2298 :
2299 : /*
2300 : * Write ready, since we've made it here, so the connection
2301 : * has been made ... or has failed.
2302 : */
2303 :
2304 : /*
2305 : * Now check (using getsockopt) that there is not an error
2306 : * state waiting for us on the socket.
2307 : */
2308 :
2309 215 : if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
2310 : (char *) &optval, &optlen) == -1)
2311 : {
2312 0 : appendPQExpBuffer(&conn->errorMessage,
2313 : libpq_gettext("could not get socket error status: %s\n"),
2314 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2315 0 : goto error_return;
2316 : }
2317 215 : else if (optval != 0)
2318 : {
2319 : /*
2320 : * When using a nonblocking connect, we will typically see
2321 : * connect failures at this point, so provide a friendly
2322 : * error message.
2323 : */
2324 0 : connectFailureMessage(conn, optval);
2325 0 : pqDropConnection(conn, true);
2326 :
2327 : /*
2328 : * If more addresses remain, keep trying, just as in the
2329 : * case where connect() returned failure immediately.
2330 : */
2331 0 : if (conn->addr_cur->ai_next != NULL ||
2332 0 : conn->whichhost + 1 < conn->nconnhost)
2333 : {
2334 0 : conn->addr_cur = conn->addr_cur->ai_next;
2335 0 : conn->status = CONNECTION_NEEDED;
2336 0 : goto keep_going;
2337 : }
2338 0 : goto error_return;
2339 : }
2340 :
2341 : /* Fill in the client address */
2342 215 : conn->laddr.salen = sizeof(conn->laddr.addr);
2343 215 : if (getsockname(conn->sock,
2344 215 : (struct sockaddr *) &conn->laddr.addr,
2345 215 : &conn->laddr.salen) < 0)
2346 : {
2347 0 : appendPQExpBuffer(&conn->errorMessage,
2348 : libpq_gettext("could not get client address from socket: %s\n"),
2349 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2350 0 : goto error_return;
2351 : }
2352 :
2353 : /*
2354 : * Make sure we can write before advancing to next step.
2355 : */
2356 215 : conn->status = CONNECTION_MADE;
2357 215 : return PGRES_POLLING_WRITING;
2358 : }
2359 :
2360 : case CONNECTION_MADE:
2361 : {
2362 : char *startpacket;
2363 : int packetlen;
2364 :
2365 : #ifdef HAVE_UNIX_SOCKETS
2366 :
2367 : /*
2368 : * Implement requirepeer check, if requested and it's a
2369 : * Unix-domain socket.
2370 : */
2371 215 : if (conn->requirepeer && conn->requirepeer[0] &&
2372 0 : IS_AF_UNIX(conn->raddr.addr.ss_family))
2373 : {
2374 : char pwdbuf[BUFSIZ];
2375 : struct passwd pass_buf;
2376 : struct passwd *pass;
2377 : int passerr;
2378 : uid_t uid;
2379 : gid_t gid;
2380 :
2381 0 : errno = 0;
2382 0 : if (getpeereid(conn->sock, &uid, &gid) != 0)
2383 : {
2384 : /*
2385 : * Provide special error message if getpeereid is a
2386 : * stub
2387 : */
2388 0 : if (errno == ENOSYS)
2389 0 : appendPQExpBufferStr(&conn->errorMessage,
2390 : libpq_gettext("requirepeer parameter is not supported on this platform\n"));
2391 : else
2392 0 : appendPQExpBuffer(&conn->errorMessage,
2393 : libpq_gettext("could not get peer credentials: %s\n"),
2394 0 : pqStrerror(errno, sebuf, sizeof(sebuf)));
2395 0 : goto error_return;
2396 : }
2397 :
2398 0 : passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
2399 0 : if (pass == NULL)
2400 : {
2401 0 : if (passerr != 0)
2402 0 : appendPQExpBuffer(&conn->errorMessage,
2403 : libpq_gettext("could not look up local user ID %d: %s\n"),
2404 : (int) uid,
2405 : pqStrerror(passerr, sebuf, sizeof(sebuf)));
2406 : else
2407 0 : appendPQExpBuffer(&conn->errorMessage,
2408 : libpq_gettext("local user with ID %d does not exist\n"),
2409 : (int) uid);
2410 0 : goto error_return;
2411 : }
2412 :
2413 0 : if (strcmp(pass->pw_name, conn->requirepeer) != 0)
2414 : {
2415 0 : appendPQExpBuffer(&conn->errorMessage,
2416 : libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
2417 0 : conn->requirepeer, pass->pw_name);
2418 0 : goto error_return;
2419 : }
2420 : }
2421 : #endif /* HAVE_UNIX_SOCKETS */
2422 :
2423 : #ifdef USE_SSL
2424 :
2425 : /*
2426 : * If SSL is enabled and we haven't already got it running,
2427 : * request it instead of sending the startup message.
2428 : */
2429 : if (IS_AF_UNIX(conn->raddr.addr.ss_family))
2430 : {
2431 : /* Don't bother requesting SSL over a Unix socket */
2432 : conn->allow_ssl_try = false;
2433 : }
2434 : if (conn->allow_ssl_try && !conn->wait_ssl_try &&
2435 : !conn->ssl_in_use)
2436 : {
2437 : ProtocolVersion pv;
2438 :
2439 : /*
2440 : * Send the SSL request packet.
2441 : *
2442 : * Theoretically, this could block, but it really
2443 : * shouldn't since we only got here if the socket is
2444 : * write-ready.
2445 : */
2446 : pv = htonl(NEGOTIATE_SSL_CODE);
2447 : if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
2448 : {
2449 : appendPQExpBuffer(&conn->errorMessage,
2450 : libpq_gettext("could not send SSL negotiation packet: %s\n"),
2451 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2452 : goto error_return;
2453 : }
2454 : /* Ok, wait for response */
2455 : conn->status = CONNECTION_SSL_STARTUP;
2456 : return PGRES_POLLING_READING;
2457 : }
2458 : #endif /* USE_SSL */
2459 :
2460 : /*
2461 : * Build the startup packet.
2462 : */
2463 215 : if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2464 215 : startpacket = pqBuildStartupPacket3(conn, &packetlen,
2465 : EnvironmentOptions);
2466 : else
2467 0 : startpacket = pqBuildStartupPacket2(conn, &packetlen,
2468 : EnvironmentOptions);
2469 215 : if (!startpacket)
2470 : {
2471 : /*
2472 : * will not appendbuffer here, since it's likely to also
2473 : * run out of memory
2474 : */
2475 0 : printfPQExpBuffer(&conn->errorMessage,
2476 : libpq_gettext("out of memory\n"));
2477 0 : goto error_return;
2478 : }
2479 :
2480 : /*
2481 : * Send the startup packet.
2482 : *
2483 : * Theoretically, this could block, but it really shouldn't
2484 : * since we only got here if the socket is write-ready.
2485 : */
2486 215 : if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
2487 : {
2488 0 : appendPQExpBuffer(&conn->errorMessage,
2489 : libpq_gettext("could not send startup packet: %s\n"),
2490 0 : SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2491 0 : free(startpacket);
2492 0 : goto error_return;
2493 : }
2494 :
2495 215 : free(startpacket);
2496 :
2497 215 : conn->status = CONNECTION_AWAITING_RESPONSE;
2498 215 : return PGRES_POLLING_READING;
2499 : }
2500 :
2501 : /*
2502 : * Handle SSL negotiation: wait for postmaster messages and
2503 : * respond as necessary.
2504 : */
2505 : case CONNECTION_SSL_STARTUP:
2506 : {
2507 : #ifdef USE_SSL
2508 : PostgresPollingStatusType pollres;
2509 :
2510 : /*
2511 : * On first time through, get the postmaster's response to our
2512 : * SSL negotiation packet.
2513 : */
2514 : if (!conn->ssl_in_use)
2515 : {
2516 : /*
2517 : * We use pqReadData here since it has the logic to
2518 : * distinguish no-data-yet from connection closure. Since
2519 : * conn->ssl isn't set, a plain recv() will occur.
2520 : */
2521 : char SSLok;
2522 : int rdresult;
2523 :
2524 : rdresult = pqReadData(conn);
2525 : if (rdresult < 0)
2526 : {
2527 : /* errorMessage is already filled in */
2528 : goto error_return;
2529 : }
2530 : if (rdresult == 0)
2531 : {
2532 : /* caller failed to wait for data */
2533 : return PGRES_POLLING_READING;
2534 : }
2535 : if (pqGetc(&SSLok, conn) < 0)
2536 : {
2537 : /* should not happen really */
2538 : return PGRES_POLLING_READING;
2539 : }
2540 : if (SSLok == 'S')
2541 : {
2542 : /* mark byte consumed */
2543 : conn->inStart = conn->inCursor;
2544 : /* Set up global SSL state if required */
2545 : if (pqsecure_initialize(conn) != 0)
2546 : goto error_return;
2547 : }
2548 : else if (SSLok == 'N')
2549 : {
2550 : /* mark byte consumed */
2551 : conn->inStart = conn->inCursor;
2552 : /* OK to do without SSL? */
2553 : if (conn->sslmode[0] == 'r' || /* "require" */
2554 : conn->sslmode[0] == 'v') /* "verify-ca" or
2555 : * "verify-full" */
2556 : {
2557 : /* Require SSL, but server does not want it */
2558 : appendPQExpBufferStr(&conn->errorMessage,
2559 : libpq_gettext("server does not support SSL, but SSL was required\n"));
2560 : goto error_return;
2561 : }
2562 : /* Otherwise, proceed with normal startup */
2563 : conn->allow_ssl_try = false;
2564 : conn->status = CONNECTION_MADE;
2565 : return PGRES_POLLING_WRITING;
2566 : }
2567 : else if (SSLok == 'E')
2568 : {
2569 : /*
2570 : * Server failure of some sort, such as failure to
2571 : * fork a backend process. We need to process and
2572 : * report the error message, which might be formatted
2573 : * according to either protocol 2 or protocol 3.
2574 : * Rather than duplicate the code for that, we flip
2575 : * into AWAITING_RESPONSE state and let the code there
2576 : * deal with it. Note we have *not* consumed the "E"
2577 : * byte here.
2578 : */
2579 : conn->status = CONNECTION_AWAITING_RESPONSE;
2580 : goto keep_going;
2581 : }
2582 : else
2583 : {
2584 : appendPQExpBuffer(&conn->errorMessage,
2585 : libpq_gettext("received invalid response to SSL negotiation: %c\n"),
2586 : SSLok);
2587 : goto error_return;
2588 : }
2589 : }
2590 :
2591 : /*
2592 : * Begin or continue the SSL negotiation process.
2593 : */
2594 : pollres = pqsecure_open_client(conn);
2595 : if (pollres == PGRES_POLLING_OK)
2596 : {
2597 : /* SSL handshake done, ready to send startup packet */
2598 : conn->status = CONNECTION_MADE;
2599 : return PGRES_POLLING_WRITING;
2600 : }
2601 : if (pollres == PGRES_POLLING_FAILED)
2602 : {
2603 : /*
2604 : * Failed ... if sslmode is "prefer" then do a non-SSL
2605 : * retry
2606 : */
2607 : if (conn->sslmode[0] == 'p' /* "prefer" */
2608 : && conn->allow_ssl_try /* redundant? */
2609 : && !conn->wait_ssl_try) /* redundant? */
2610 : {
2611 : /* only retry once */
2612 : conn->allow_ssl_try = false;
2613 : /* Must drop the old connection */
2614 : pqDropConnection(conn, true);
2615 : conn->status = CONNECTION_NEEDED;
2616 : goto keep_going;
2617 : }
2618 : }
2619 : return pollres;
2620 : #else /* !USE_SSL */
2621 : /* can't get here */
2622 0 : goto error_return;
2623 : #endif /* USE_SSL */
2624 : }
2625 :
2626 : /*
2627 : * Handle authentication exchange: wait for postmaster messages
2628 : * and respond as necessary.
2629 : */
2630 : case CONNECTION_AWAITING_RESPONSE:
2631 : {
2632 : char beresp;
2633 : int msgLength;
2634 : int avail;
2635 : AuthRequest areq;
2636 : int res;
2637 :
2638 : /*
2639 : * Scan the message from current point (note that if we find
2640 : * the message is incomplete, we will return without advancing
2641 : * inStart, and resume here next time).
2642 : */
2643 215 : conn->inCursor = conn->inStart;
2644 :
2645 : /* Read type byte */
2646 215 : if (pqGetc(&beresp, conn))
2647 : {
2648 : /* We'll come back when there is more data */
2649 0 : return PGRES_POLLING_READING;
2650 : }
2651 :
2652 : /*
2653 : * Validate message type: we expect only an authentication
2654 : * request or an error here. Anything else probably means
2655 : * it's not Postgres on the other end at all.
2656 : */
2657 215 : if (!(beresp == 'R' || beresp == 'E'))
2658 : {
2659 0 : appendPQExpBuffer(&conn->errorMessage,
2660 : libpq_gettext(
2661 : "expected authentication request from "
2662 : "server, but received %c\n"),
2663 : beresp);
2664 0 : goto error_return;
2665 : }
2666 :
2667 215 : if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2668 : {
2669 : /* Read message length word */
2670 215 : if (pqGetInt(&msgLength, 4, conn))
2671 : {
2672 : /* We'll come back when there is more data */
2673 0 : return PGRES_POLLING_READING;
2674 : }
2675 : }
2676 : else
2677 : {
2678 : /* Set phony message length to disable checks below */
2679 0 : msgLength = 8;
2680 : }
2681 :
2682 : /*
2683 : * Try to validate message length before using it.
2684 : * Authentication requests can't be very large, although GSS
2685 : * auth requests may not be that small. Errors can be a
2686 : * little larger, but not huge. If we see a large apparent
2687 : * length in an error, it means we're really talking to a
2688 : * pre-3.0-protocol server; cope.
2689 : */
2690 215 : if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
2691 : {
2692 0 : appendPQExpBuffer(&conn->errorMessage,
2693 : libpq_gettext(
2694 : "expected authentication request from "
2695 : "server, but received %c\n"),
2696 : beresp);
2697 0 : goto error_return;
2698 : }
2699 :
2700 215 : if (beresp == 'E' && (msgLength < 8 || msgLength > 30000))
2701 : {
2702 : /* Handle error from a pre-3.0 server */
2703 0 : conn->inCursor = conn->inStart + 1; /* reread data */
2704 0 : if (pqGets_append(&conn->errorMessage, conn))
2705 : {
2706 : /* We'll come back when there is more data */
2707 0 : return PGRES_POLLING_READING;
2708 : }
2709 : /* OK, we read the message; mark data consumed */
2710 0 : conn->inStart = conn->inCursor;
2711 :
2712 : /*
2713 : * The postmaster typically won't end its message with a
2714 : * newline, so add one to conform to libpq conventions.
2715 : */
2716 0 : appendPQExpBufferChar(&conn->errorMessage, '\n');
2717 :
2718 : /*
2719 : * If we tried to open the connection in 3.0 protocol,
2720 : * fall back to 2.0 protocol.
2721 : */
2722 0 : if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2723 : {
2724 0 : conn->pversion = PG_PROTOCOL(2, 0);
2725 : /* Must drop the old connection */
2726 0 : pqDropConnection(conn, true);
2727 0 : conn->status = CONNECTION_NEEDED;
2728 215 : goto keep_going;
2729 : }
2730 :
2731 0 : goto error_return;
2732 : }
2733 :
2734 : /*
2735 : * Can't process if message body isn't all here yet.
2736 : *
2737 : * (In protocol 2.0 case, we are assuming messages carry at
2738 : * least 4 bytes of data.)
2739 : */
2740 215 : msgLength -= 4;
2741 215 : avail = conn->inEnd - conn->inCursor;
2742 215 : if (avail < msgLength)
2743 : {
2744 : /*
2745 : * Before returning, try to enlarge the input buffer if
2746 : * needed to hold the whole message; see notes in
2747 : * pqParseInput3.
2748 : */
2749 0 : if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2750 : conn))
2751 0 : goto error_return;
2752 : /* We'll come back when there is more data */
2753 0 : return PGRES_POLLING_READING;
2754 : }
2755 :
2756 : /* Handle errors. */
2757 215 : if (beresp == 'E')
2758 : {
2759 0 : if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2760 : {
2761 0 : if (pqGetErrorNotice3(conn, true))
2762 : {
2763 : /* We'll come back when there is more data */
2764 0 : return PGRES_POLLING_READING;
2765 : }
2766 : }
2767 : else
2768 : {
2769 0 : if (pqGets_append(&conn->errorMessage, conn))
2770 : {
2771 : /* We'll come back when there is more data */
2772 0 : return PGRES_POLLING_READING;
2773 : }
2774 : }
2775 : /* OK, we read the message; mark data consumed */
2776 0 : conn->inStart = conn->inCursor;
2777 :
2778 : #ifdef USE_SSL
2779 :
2780 : /*
2781 : * if sslmode is "allow" and we haven't tried an SSL
2782 : * connection already, then retry with an SSL connection
2783 : */
2784 : if (conn->sslmode[0] == 'a' /* "allow" */
2785 : && !conn->ssl_in_use
2786 : && conn->allow_ssl_try
2787 : && conn->wait_ssl_try)
2788 : {
2789 : /* only retry once */
2790 : conn->wait_ssl_try = false;
2791 : /* Must drop the old connection */
2792 : pqDropConnection(conn, true);
2793 : conn->status = CONNECTION_NEEDED;
2794 : goto keep_going;
2795 : }
2796 :
2797 : /*
2798 : * if sslmode is "prefer" and we're in an SSL connection,
2799 : * then do a non-SSL retry
2800 : */
2801 : if (conn->sslmode[0] == 'p' /* "prefer" */
2802 : && conn->allow_ssl_try
2803 : && !conn->wait_ssl_try) /* redundant? */
2804 : {
2805 : /* only retry once */
2806 : conn->allow_ssl_try = false;
2807 : /* Must drop the old connection */
2808 : pqDropConnection(conn, true);
2809 : conn->status = CONNECTION_NEEDED;
2810 : goto keep_going;
2811 : }
2812 : #endif
2813 :
2814 0 : goto error_return;
2815 : }
2816 :
2817 : /* It is an authentication request. */
2818 215 : conn->auth_req_received = true;
2819 :
2820 : /* Get the type of request. */
2821 215 : if (pqGetInt((int *) &areq, 4, conn))
2822 : {
2823 : /* We'll come back when there are more data */
2824 0 : return PGRES_POLLING_READING;
2825 : }
2826 215 : msgLength -= 4;
2827 :
2828 : /*
2829 : * Ensure the password salt is in the input buffer, if it's an
2830 : * MD5 request. All the other authentication methods that
2831 : * contain extra data in the authentication request are only
2832 : * supported in protocol version 3, in which case we already
2833 : * read the whole message above.
2834 : */
2835 215 : if (areq == AUTH_REQ_MD5 && PG_PROTOCOL_MAJOR(conn->pversion) < 3)
2836 : {
2837 0 : msgLength += 4;
2838 :
2839 0 : avail = conn->inEnd - conn->inCursor;
2840 0 : if (avail < 4)
2841 : {
2842 : /*
2843 : * Before returning, try to enlarge the input buffer
2844 : * if needed to hold the whole message; see notes in
2845 : * pqParseInput3.
2846 : */
2847 0 : if (pqCheckInBufferSpace(conn->inCursor + (size_t) 4,
2848 : conn))
2849 0 : goto error_return;
2850 : /* We'll come back when there is more data */
2851 0 : return PGRES_POLLING_READING;
2852 : }
2853 : }
2854 :
2855 : /*
2856 : * Process the rest of the authentication request message, and
2857 : * respond to it if necessary.
2858 : *
2859 : * Note that conn->pghost must be non-NULL if we are going to
2860 : * avoid the Kerberos code doing a hostname look-up.
2861 : */
2862 215 : res = pg_fe_sendauth(areq, msgLength, conn);
2863 215 : conn->errorMessage.len = strlen(conn->errorMessage.data);
2864 :
2865 : /* OK, we have processed the message; mark data consumed */
2866 215 : conn->inStart = conn->inCursor;
2867 :
2868 215 : if (res != STATUS_OK)
2869 0 : goto error_return;
2870 :
2871 : /*
2872 : * Just make sure that any data sent by pg_fe_sendauth is
2873 : * flushed out. Although this theoretically could block, it
2874 : * really shouldn't since we don't send large auth responses.
2875 : */
2876 215 : if (pqFlush(conn))
2877 0 : goto error_return;
2878 :
2879 215 : if (areq == AUTH_REQ_OK)
2880 : {
2881 : /* We are done with authentication exchange */
2882 215 : conn->status = CONNECTION_AUTH_OK;
2883 :
2884 : /*
2885 : * Set asyncStatus so that PQgetResult will think that
2886 : * what comes back next is the result of a query. See
2887 : * below.
2888 : */
2889 215 : conn->asyncStatus = PGASYNC_BUSY;
2890 : }
2891 :
2892 : /* Look to see if we have more data yet. */
2893 215 : goto keep_going;
2894 : }
2895 :
2896 : case CONNECTION_AUTH_OK:
2897 : {
2898 : /*
2899 : * Now we expect to hear from the backend. A ReadyForQuery
2900 : * message indicates that startup is successful, but we might
2901 : * also get an Error message indicating failure. (Notice
2902 : * messages indicating nonfatal warnings are also allowed by
2903 : * the protocol, as are ParameterStatus and BackendKeyData
2904 : * messages.) Easiest way to handle this is to let
2905 : * PQgetResult() read the messages. We just have to fake it
2906 : * out about the state of the connection, by setting
2907 : * asyncStatus = PGASYNC_BUSY (done above).
2908 : */
2909 :
2910 215 : if (PQisBusy(conn))
2911 0 : return PGRES_POLLING_READING;
2912 :
2913 215 : res = PQgetResult(conn);
2914 :
2915 : /*
2916 : * NULL return indicating we have gone to IDLE state is
2917 : * expected
2918 : */
2919 215 : if (res)
2920 : {
2921 0 : if (res->resultStatus != PGRES_FATAL_ERROR)
2922 0 : appendPQExpBufferStr(&conn->errorMessage,
2923 : libpq_gettext("unexpected message from server during startup\n"));
2924 0 : else if (conn->send_appname &&
2925 0 : (conn->appname || conn->fbappname))
2926 : {
2927 : /*
2928 : * If we tried to send application_name, check to see
2929 : * if the error is about that --- pre-9.0 servers will
2930 : * reject it at this stage of the process. If so,
2931 : * close the connection and retry without sending
2932 : * application_name. We could possibly get a false
2933 : * SQLSTATE match here and retry uselessly, but there
2934 : * seems no great harm in that; we'll just get the
2935 : * same error again if it's unrelated.
2936 : */
2937 : const char *sqlstate;
2938 :
2939 0 : sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
2940 0 : if (sqlstate &&
2941 0 : strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
2942 : {
2943 0 : PQclear(res);
2944 0 : conn->send_appname = false;
2945 : /* Must drop the old connection */
2946 0 : pqDropConnection(conn, true);
2947 0 : conn->status = CONNECTION_NEEDED;
2948 0 : goto keep_going;
2949 : }
2950 : }
2951 :
2952 : /*
2953 : * if the resultStatus is FATAL, then conn->errorMessage
2954 : * already has a copy of the error; needn't copy it back.
2955 : * But add a newline if it's not there already, since
2956 : * postmaster error messages may not have one.
2957 : */
2958 0 : if (conn->errorMessage.len <= 0 ||
2959 0 : conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
2960 0 : appendPQExpBufferChar(&conn->errorMessage, '\n');
2961 0 : PQclear(res);
2962 0 : goto error_return;
2963 : }
2964 :
2965 : /* Fire up post-connection housekeeping if needed */
2966 215 : if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
2967 : {
2968 0 : conn->status = CONNECTION_SETENV;
2969 0 : conn->setenv_state = SETENV_STATE_CLIENT_ENCODING_SEND;
2970 0 : conn->next_eo = EnvironmentOptions;
2971 0 : return PGRES_POLLING_WRITING;
2972 : }
2973 :
2974 : /*
2975 : * If a read-write connection is required, see if we have one.
2976 : */
2977 430 : if (conn->target_session_attrs != NULL &&
2978 215 : strcmp(conn->target_session_attrs, "read-write") == 0)
2979 : {
2980 : /*
2981 : * We are yet to make a connection. Save all existing
2982 : * error messages until we make a successful connection
2983 : * state. This is important because PQsendQuery is going
2984 : * to reset conn->errorMessage and we will lose error
2985 : * messages related to previous hosts we have tried to
2986 : * connect and failed.
2987 : */
2988 0 : if (!saveErrorMessage(conn, &savedMessage))
2989 0 : goto error_return;
2990 :
2991 0 : conn->status = CONNECTION_OK;
2992 0 : if (!PQsendQuery(conn,
2993 : "SHOW transaction_read_only"))
2994 : {
2995 0 : restoreErrorMessage(conn, &savedMessage);
2996 0 : goto error_return;
2997 : }
2998 0 : conn->status = CONNECTION_CHECK_WRITABLE;
2999 0 : restoreErrorMessage(conn, &savedMessage);
3000 0 : return PGRES_POLLING_READING;
3001 : }
3002 :
3003 : /* We can release the address lists now. */
3004 215 : release_all_addrinfo(conn);
3005 :
3006 : /* We are open for business! */
3007 215 : conn->status = CONNECTION_OK;
3008 215 : return PGRES_POLLING_OK;
3009 : }
3010 :
3011 : case CONNECTION_SETENV:
3012 :
3013 : /*
3014 : * Do post-connection housekeeping (only needed in protocol 2.0).
3015 : *
3016 : * We pretend that the connection is OK for the duration of these
3017 : * queries.
3018 : */
3019 0 : conn->status = CONNECTION_OK;
3020 :
3021 0 : switch (pqSetenvPoll(conn))
3022 : {
3023 : case PGRES_POLLING_OK: /* Success */
3024 0 : break;
3025 :
3026 : case PGRES_POLLING_READING: /* Still going */
3027 0 : conn->status = CONNECTION_SETENV;
3028 0 : return PGRES_POLLING_READING;
3029 :
3030 : case PGRES_POLLING_WRITING: /* Still going */
3031 0 : conn->status = CONNECTION_SETENV;
3032 0 : return PGRES_POLLING_WRITING;
3033 :
3034 : default:
3035 0 : goto error_return;
3036 : }
3037 :
3038 : /*
3039 : * If a read-write connection is requested check for same.
3040 : */
3041 0 : if (conn->target_session_attrs != NULL &&
3042 0 : strcmp(conn->target_session_attrs, "read-write") == 0)
3043 : {
3044 0 : if (!saveErrorMessage(conn, &savedMessage))
3045 0 : goto error_return;
3046 :
3047 0 : conn->status = CONNECTION_OK;
3048 0 : if (!PQsendQuery(conn,
3049 : "SHOW transaction_read_only"))
3050 : {
3051 0 : restoreErrorMessage(conn, &savedMessage);
3052 0 : goto error_return;
3053 : }
3054 0 : conn->status = CONNECTION_CHECK_WRITABLE;
3055 0 : restoreErrorMessage(conn, &savedMessage);
3056 0 : return PGRES_POLLING_READING;
3057 : }
3058 :
3059 : /* We can release the address lists now. */
3060 0 : release_all_addrinfo(conn);
3061 :
3062 : /* We are open for business! */
3063 0 : conn->status = CONNECTION_OK;
3064 0 : return PGRES_POLLING_OK;
3065 :
3066 : case CONNECTION_CONSUME:
3067 : {
3068 0 : conn->status = CONNECTION_OK;
3069 0 : if (!PQconsumeInput(conn))
3070 0 : goto error_return;
3071 :
3072 0 : if (PQisBusy(conn))
3073 : {
3074 0 : conn->status = CONNECTION_CONSUME;
3075 0 : restoreErrorMessage(conn, &savedMessage);
3076 0 : return PGRES_POLLING_READING;
3077 : }
3078 :
3079 : /*
3080 : * Call PQgetResult() again to consume NULL result.
3081 : */
3082 0 : res = PQgetResult(conn);
3083 0 : if (res != NULL)
3084 : {
3085 0 : PQclear(res);
3086 0 : conn->status = CONNECTION_CONSUME;
3087 0 : goto keep_going;
3088 : }
3089 :
3090 : /* We are open for business! */
3091 0 : conn->status = CONNECTION_OK;
3092 0 : return PGRES_POLLING_OK;
3093 : }
3094 : case CONNECTION_CHECK_WRITABLE:
3095 : {
3096 : const char *displayed_host;
3097 : const char *displayed_port;
3098 :
3099 0 : if (!saveErrorMessage(conn, &savedMessage))
3100 0 : goto error_return;
3101 :
3102 0 : conn->status = CONNECTION_OK;
3103 0 : if (!PQconsumeInput(conn))
3104 : {
3105 0 : restoreErrorMessage(conn, &savedMessage);
3106 0 : goto error_return;
3107 : }
3108 :
3109 0 : if (PQisBusy(conn))
3110 : {
3111 0 : conn->status = CONNECTION_CHECK_WRITABLE;
3112 0 : restoreErrorMessage(conn, &savedMessage);
3113 0 : return PGRES_POLLING_READING;
3114 : }
3115 :
3116 0 : res = PQgetResult(conn);
3117 0 : if (res && (PQresultStatus(res) == PGRES_TUPLES_OK) &&
3118 0 : PQntuples(res) == 1)
3119 : {
3120 : char *val;
3121 :
3122 0 : val = PQgetvalue(res, 0, 0);
3123 0 : if (strncmp(val, "on", 2) == 0)
3124 : {
3125 : const char *displayed_host;
3126 : const char *displayed_port;
3127 :
3128 0 : if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
3129 0 : displayed_host = conn->connhost[conn->whichhost].hostaddr;
3130 : else
3131 0 : displayed_host = conn->connhost[conn->whichhost].host;
3132 0 : displayed_port = conn->connhost[conn->whichhost].port;
3133 0 : if (displayed_port == NULL || displayed_port[0] == '\0')
3134 0 : displayed_port = DEF_PGPORT_STR;
3135 :
3136 0 : PQclear(res);
3137 0 : restoreErrorMessage(conn, &savedMessage);
3138 :
3139 : /* Not writable; close connection. */
3140 0 : appendPQExpBuffer(&conn->errorMessage,
3141 : libpq_gettext("could not make a writable "
3142 : "connection to server "
3143 : "\"%s:%s\"\n"),
3144 : displayed_host, displayed_port);
3145 0 : conn->status = CONNECTION_OK;
3146 0 : sendTerminateConn(conn);
3147 0 : pqDropConnection(conn, true);
3148 :
3149 : /* Skip any remaining addresses for this host. */
3150 0 : conn->addr_cur = NULL;
3151 0 : if (conn->whichhost + 1 < conn->nconnhost)
3152 : {
3153 0 : conn->status = CONNECTION_NEEDED;
3154 0 : goto keep_going;
3155 : }
3156 :
3157 : /* No more addresses to try. So we fail. */
3158 0 : goto error_return;
3159 : }
3160 0 : PQclear(res);
3161 0 : termPQExpBuffer(&savedMessage);
3162 :
3163 : /* We can release the address lists now. */
3164 0 : release_all_addrinfo(conn);
3165 :
3166 : /*
3167 : * Finish reading any remaining messages before being
3168 : * considered as ready.
3169 : */
3170 0 : conn->status = CONNECTION_CONSUME;
3171 0 : goto keep_going;
3172 : }
3173 :
3174 : /*
3175 : * Something went wrong with "SHOW transaction_read_only". We
3176 : * should try next addresses.
3177 : */
3178 0 : if (res)
3179 0 : PQclear(res);
3180 0 : restoreErrorMessage(conn, &savedMessage);
3181 :
3182 0 : if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
3183 0 : displayed_host = conn->connhost[conn->whichhost].hostaddr;
3184 : else
3185 0 : displayed_host = conn->connhost[conn->whichhost].host;
3186 0 : displayed_port = conn->connhost[conn->whichhost].port;
3187 0 : if (displayed_port == NULL || displayed_port[0] == '\0')
3188 0 : displayed_port = DEF_PGPORT_STR;
3189 0 : appendPQExpBuffer(&conn->errorMessage,
3190 : libpq_gettext("test \"SHOW transaction_read_only\" failed "
3191 : "on server \"%s:%s\"\n"),
3192 : displayed_host, displayed_port);
3193 0 : conn->status = CONNECTION_OK;
3194 0 : sendTerminateConn(conn);
3195 0 : pqDropConnection(conn, true);
3196 :
3197 0 : if (conn->addr_cur->ai_next != NULL ||
3198 0 : conn->whichhost + 1 < conn->nconnhost)
3199 : {
3200 0 : conn->addr_cur = conn->addr_cur->ai_next;
3201 0 : conn->status = CONNECTION_NEEDED;
3202 0 : goto keep_going;
3203 : }
3204 :
3205 : /* No more addresses to try. So we fail. */
3206 0 : goto error_return;
3207 : }
3208 :
3209 : default:
3210 0 : appendPQExpBuffer(&conn->errorMessage,
3211 : libpq_gettext("invalid connection state %d, "
3212 : "probably indicative of memory corruption\n"),
3213 0 : conn->status);
3214 0 : goto error_return;
3215 : }
3216 :
3217 : /* Unreachable */
3218 :
3219 : error_return:
3220 :
3221 2 : pgpassfileWarning(conn);
3222 :
3223 : /*
3224 : * We used to close the socket at this point, but that makes it awkward
3225 : * for those above us if they wish to remove this socket from their own
3226 : * records (an fd_set for example). We'll just have this socket closed
3227 : * when PQfinish is called (which is compulsory even after an error, since
3228 : * the connection structure must be freed).
3229 : */
3230 2 : conn->status = CONNECTION_BAD;
3231 2 : return PGRES_POLLING_FAILED;
3232 : }
3233 :
3234 :
3235 : /*
3236 : * internal_ping
3237 : * Determine if a server is running and if we can connect to it.
3238 : *
3239 : * The argument is a connection that's been started, but not completed.
3240 : */
3241 : static PGPing
3242 0 : internal_ping(PGconn *conn)
3243 : {
3244 : /* Say "no attempt" if we never got to PQconnectPoll */
3245 0 : if (!conn || !conn->options_valid)
3246 0 : return PQPING_NO_ATTEMPT;
3247 :
3248 : /* Attempt to complete the connection */
3249 0 : if (conn->status != CONNECTION_BAD)
3250 0 : (void) connectDBComplete(conn);
3251 :
3252 : /* Definitely OK if we succeeded */
3253 0 : if (conn->status != CONNECTION_BAD)
3254 0 : return PQPING_OK;
3255 :
3256 : /*
3257 : * Here begins the interesting part of "ping": determine the cause of the
3258 : * failure in sufficient detail to decide what to return. We do not want
3259 : * to report that the server is not up just because we didn't have a valid
3260 : * password, for example. In fact, any sort of authentication request
3261 : * implies the server is up. (We need this check since the libpq side of
3262 : * things might have pulled the plug on the connection before getting an
3263 : * error as such from the postmaster.)
3264 : */
3265 0 : if (conn->auth_req_received)
3266 0 : return PQPING_OK;
3267 :
3268 : /*
3269 : * If we failed to get any ERROR response from the postmaster, report
3270 : * PQPING_NO_RESPONSE. This result could be somewhat misleading for a
3271 : * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3272 : * out of support. Another corner case where the server could return a
3273 : * failure without a SQLSTATE is fork failure, but NO_RESPONSE isn't
3274 : * totally unreasonable for that anyway. We expect that every other
3275 : * failure case in a modern server will produce a report with a SQLSTATE.
3276 : *
3277 : * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3278 : * client-side errors, we should either not store those into
3279 : * last_sqlstate, or add an extra flag so we can tell client-side errors
3280 : * apart from server-side ones.
3281 : */
3282 0 : if (strlen(conn->last_sqlstate) != 5)
3283 0 : return PQPING_NO_RESPONSE;
3284 :
3285 : /*
3286 : * Report PQPING_REJECT if server says it's not accepting connections. (We
3287 : * distinguish this case mainly for the convenience of pg_ctl.)
3288 : */
3289 0 : if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3290 0 : return PQPING_REJECT;
3291 :
3292 : /*
3293 : * Any other SQLSTATE can be taken to indicate that the server is up.
3294 : * Presumably it didn't like our username, password, or database name; or
3295 : * perhaps it had some transient failure, but that should not be taken as
3296 : * meaning "it's down".
3297 : */
3298 0 : return PQPING_OK;
3299 : }
3300 :
3301 :
3302 : /*
3303 : * makeEmptyPGconn
3304 : * - create a PGconn data structure with (as yet) no interesting data
3305 : */
3306 : static PGconn *
3307 217 : makeEmptyPGconn(void)
3308 : {
3309 : PGconn *conn;
3310 :
3311 : #ifdef WIN32
3312 :
3313 : /*
3314 : * Make sure socket support is up and running.
3315 : */
3316 : WSADATA wsaData;
3317 :
3318 : if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3319 : return NULL;
3320 : WSASetLastError(0);
3321 : #endif
3322 :
3323 217 : conn = (PGconn *) malloc(sizeof(PGconn));
3324 217 : if (conn == NULL)
3325 : {
3326 : #ifdef WIN32
3327 : WSACleanup();
3328 : #endif
3329 0 : return conn;
3330 : }
3331 :
3332 : /* Zero all pointers and booleans */
3333 217 : MemSet(conn, 0, sizeof(PGconn));
3334 :
3335 : /* install default notice hooks */
3336 217 : conn->noticeHooks.noticeRec = defaultNoticeReceiver;
3337 217 : conn->noticeHooks.noticeProc = defaultNoticeProcessor;
3338 :
3339 217 : conn->status = CONNECTION_BAD;
3340 217 : conn->asyncStatus = PGASYNC_IDLE;
3341 217 : conn->xactStatus = PQTRANS_IDLE;
3342 217 : conn->options_valid = false;
3343 217 : conn->nonblocking = false;
3344 217 : conn->setenv_state = SETENV_STATE_IDLE;
3345 217 : conn->client_encoding = PG_SQL_ASCII;
3346 217 : conn->std_strings = false; /* unless server says differently */
3347 217 : conn->verbosity = PQERRORS_DEFAULT;
3348 217 : conn->show_context = PQSHOW_CONTEXT_ERRORS;
3349 217 : conn->sock = PGINVALID_SOCKET;
3350 217 : conn->auth_req_received = false;
3351 217 : conn->password_needed = false;
3352 217 : conn->pgpassfile_used = false;
3353 : #ifdef USE_SSL
3354 : conn->allow_ssl_try = true;
3355 : conn->wait_ssl_try = false;
3356 : conn->ssl_in_use = false;
3357 : #endif
3358 :
3359 : /*
3360 : * We try to send at least 8K at a time, which is the usual size of pipe
3361 : * buffers on Unix systems. That way, when we are sending a large amount
3362 : * of data, we avoid incurring extra kernel context swaps for partial
3363 : * bufferloads. The output buffer is initially made 16K in size, and we
3364 : * try to dump it after accumulating 8K.
3365 : *
3366 : * With the same goal of minimizing context swaps, the input buffer will
3367 : * be enlarged anytime it has less than 8K free, so we initially allocate
3368 : * twice that.
3369 : */
3370 217 : conn->inBufSize = 16 * 1024;
3371 217 : conn->inBuffer = (char *) malloc(conn->inBufSize);
3372 217 : conn->outBufSize = 16 * 1024;
3373 217 : conn->outBuffer = (char *) malloc(conn->outBufSize);
3374 217 : conn->rowBufLen = 32;
3375 217 : conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3376 217 : initPQExpBuffer(&conn->errorMessage);
3377 217 : initPQExpBuffer(&conn->workBuffer);
3378 :
3379 434 : if (conn->inBuffer == NULL ||
3380 434 : conn->outBuffer == NULL ||
3381 434 : conn->rowBuf == NULL ||
3382 651 : PQExpBufferBroken(&conn->errorMessage) ||
3383 434 : PQExpBufferBroken(&conn->workBuffer))
3384 : {
3385 : /* out of memory already :-( */
3386 0 : freePGconn(conn);
3387 0 : conn = NULL;
3388 : }
3389 :
3390 217 : return conn;
3391 : }
3392 :
3393 : /*
3394 : * freePGconn
3395 : * - free an idle (closed) PGconn data structure
3396 : *
3397 : * NOTE: this should not overlap any functionality with closePGconn().
3398 : * Clearing/resetting of transient state belongs there; what we do here is
3399 : * release data that is to be held for the life of the PGconn structure.
3400 : * If a value ought to be cleared/freed during PQreset(), do it there not here.
3401 : */
3402 : static void
3403 217 : freePGconn(PGconn *conn)
3404 : {
3405 : int i;
3406 :
3407 : /* let any event procs clean up their state data */
3408 217 : for (i = 0; i < conn->nEvents; i++)
3409 : {
3410 : PGEventConnDestroy evt;
3411 :
3412 0 : evt.conn = conn;
3413 0 : (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3414 0 : conn->events[i].passThrough);
3415 0 : free(conn->events[i].name);
3416 : }
3417 :
3418 : /* clean up pg_conn_host structures */
3419 217 : if (conn->connhost != NULL)
3420 : {
3421 434 : for (i = 0; i < conn->nconnhost; ++i)
3422 : {
3423 217 : if (conn->connhost[i].host != NULL)
3424 217 : free(conn->connhost[i].host);
3425 217 : if (conn->connhost[i].hostaddr != NULL)
3426 0 : free(conn->connhost[i].hostaddr);
3427 217 : if (conn->connhost[i].port != NULL)
3428 217 : free(conn->connhost[i].port);
3429 217 : if (conn->connhost[i].password != NULL)
3430 0 : free(conn->connhost[i].password);
3431 : }
3432 217 : free(conn->connhost);
3433 : }
3434 :
3435 217 : if (conn->client_encoding_initial)
3436 2 : free(conn->client_encoding_initial);
3437 217 : if (conn->events)
3438 0 : free(conn->events);
3439 217 : if (conn->pghost)
3440 217 : free(conn->pghost);
3441 217 : if (conn->pghostaddr)
3442 0 : free(conn->pghostaddr);
3443 217 : if (conn->pgport)
3444 217 : free(conn->pgport);
3445 217 : if (conn->pgtty)
3446 217 : free(conn->pgtty);
3447 217 : if (conn->connect_timeout)
3448 0 : free(conn->connect_timeout);
3449 217 : if (conn->pgoptions)
3450 217 : free(conn->pgoptions);
3451 217 : if (conn->appname)
3452 217 : free(conn->appname);
3453 217 : if (conn->fbappname)
3454 217 : free(conn->fbappname);
3455 217 : if (conn->dbName)
3456 217 : free(conn->dbName);
3457 217 : if (conn->replication)
3458 0 : free(conn->replication);
3459 217 : if (conn->pguser)
3460 217 : free(conn->pguser);
3461 217 : if (conn->pgpass)
3462 0 : free(conn->pgpass);
3463 217 : if (conn->pgpassfile)
3464 217 : free(conn->pgpassfile);
3465 217 : if (conn->keepalives)
3466 0 : free(conn->keepalives);
3467 217 : if (conn->keepalives_idle)
3468 0 : free(conn->keepalives_idle);
3469 217 : if (conn->keepalives_interval)
3470 0 : free(conn->keepalives_interval);
3471 217 : if (conn->keepalives_count)
3472 0 : free(conn->keepalives_count);
3473 217 : if (conn->sslmode)
3474 217 : free(conn->sslmode);
3475 217 : if (conn->sslcert)
3476 0 : free(conn->sslcert);
3477 217 : if (conn->sslkey)
3478 0 : free(conn->sslkey);
3479 217 : if (conn->sslrootcert)
3480 0 : free(conn->sslrootcert);
3481 217 : if (conn->sslcrl)
3482 0 : free(conn->sslcrl);
3483 217 : if (conn->sslcompression)
3484 217 : free(conn->sslcompression);
3485 217 : if (conn->requirepeer)
3486 0 : free(conn->requirepeer);
3487 : #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3488 : if (conn->krbsrvname)
3489 : free(conn->krbsrvname);
3490 : #endif
3491 : #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3492 : if (conn->gsslib)
3493 : free(conn->gsslib);
3494 : #endif
3495 : /* Note that conn->Pfdebug is not ours to close or free */
3496 217 : if (conn->last_query)
3497 214 : free(conn->last_query);
3498 217 : if (conn->inBuffer)
3499 217 : free(conn->inBuffer);
3500 217 : if (conn->outBuffer)
3501 217 : free(conn->outBuffer);
3502 217 : if (conn->rowBuf)
3503 217 : free(conn->rowBuf);
3504 217 : if (conn->target_session_attrs)
3505 217 : free(conn->target_session_attrs);
3506 217 : termPQExpBuffer(&conn->errorMessage);
3507 217 : termPQExpBuffer(&conn->workBuffer);
3508 :
3509 217 : free(conn);
3510 :
3511 : #ifdef WIN32
3512 : WSACleanup();
3513 : #endif
3514 217 : }
3515 :
3516 : /*
3517 : * release_all_addrinfo
3518 : * - free addrinfo of all hostconn elements.
3519 : */
3520 :
3521 : static void
3522 432 : release_all_addrinfo(PGconn *conn)
3523 : {
3524 432 : if (conn->connhost != NULL)
3525 : {
3526 : int i;
3527 :
3528 864 : for (i = 0; i < conn->nconnhost; ++i)
3529 : {
3530 432 : int family = AF_UNSPEC;
3531 :
3532 : #ifdef HAVE_UNIX_SOCKETS
3533 432 : if (conn->connhost[i].type == CHT_UNIX_SOCKET)
3534 432 : family = AF_UNIX;
3535 : #endif
3536 :
3537 432 : pg_freeaddrinfo_all(family,
3538 432 : conn->connhost[i].addrlist);
3539 432 : conn->connhost[i].addrlist = NULL;
3540 : }
3541 : }
3542 432 : conn->addr_cur = NULL;
3543 432 : }
3544 :
3545 : /*
3546 : * sendTerminateConn
3547 : * - Send a terminate message to backend.
3548 : */
3549 : static void
3550 217 : sendTerminateConn(PGconn *conn)
3551 : {
3552 : /*
3553 : * Note that the protocol doesn't allow us to send Terminate messages
3554 : * during the startup phase.
3555 : */
3556 217 : if (conn->sock != PGINVALID_SOCKET && conn->status == CONNECTION_OK)
3557 : {
3558 : /*
3559 : * Try to send "close connection" message to backend. Ignore any
3560 : * error.
3561 : */
3562 215 : pqPutMsgStart('X', false, conn);
3563 215 : pqPutMsgEnd(conn);
3564 215 : (void) pqFlush(conn);
3565 : }
3566 217 : }
3567 :
3568 : /*
3569 : * closePGconn
3570 : * - properly close a connection to the backend
3571 : *
3572 : * This should reset or release all transient state, but NOT the connection
3573 : * parameters. On exit, the PGconn should be in condition to start a fresh
3574 : * connection with the same parameters (see PQreset()).
3575 : */
3576 : static void
3577 217 : closePGconn(PGconn *conn)
3578 : {
3579 : PGnotify *notify;
3580 : pgParameterStatus *pstatus;
3581 :
3582 217 : sendTerminateConn(conn);
3583 :
3584 : /*
3585 : * Must reset the blocking status so a possible reconnect will work.
3586 : *
3587 : * Don't call PQsetnonblocking() because it will fail if it's unable to
3588 : * flush the connection.
3589 : */
3590 217 : conn->nonblocking = FALSE;
3591 :
3592 : /*
3593 : * Close the connection, reset all transient state, flush I/O buffers.
3594 : */
3595 217 : pqDropConnection(conn, true);
3596 217 : conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
3597 217 : conn->asyncStatus = PGASYNC_IDLE;
3598 217 : pqClearAsyncResult(conn); /* deallocate result */
3599 217 : resetPQExpBuffer(&conn->errorMessage);
3600 217 : release_all_addrinfo(conn);
3601 :
3602 217 : notify = conn->notifyHead;
3603 434 : while (notify != NULL)
3604 : {
3605 0 : PGnotify *prev = notify;
3606 :
3607 0 : notify = notify->next;
3608 0 : free(prev);
3609 : }
3610 217 : conn->notifyHead = conn->notifyTail = NULL;
3611 217 : pstatus = conn->pstatus;
3612 2799 : while (pstatus != NULL)
3613 : {
3614 2365 : pgParameterStatus *prev = pstatus;
3615 :
3616 2365 : pstatus = pstatus->next;
3617 2365 : free(prev);
3618 : }
3619 217 : conn->pstatus = NULL;
3620 217 : if (conn->lobjfuncs)
3621 1 : free(conn->lobjfuncs);
3622 217 : conn->lobjfuncs = NULL;
3623 217 : }
3624 :
3625 : /*
3626 : * PQfinish: properly close a connection to the backend. Also frees
3627 : * the PGconn data structure so it shouldn't be re-used after this.
3628 : */
3629 : void
3630 217 : PQfinish(PGconn *conn)
3631 : {
3632 217 : if (conn)
3633 : {
3634 217 : closePGconn(conn);
3635 217 : freePGconn(conn);
3636 : }
3637 217 : }
3638 :
3639 : /*
3640 : * PQreset: resets the connection to the backend by closing the
3641 : * existing connection and creating a new one.
3642 : */
3643 : void
3644 0 : PQreset(PGconn *conn)
3645 : {
3646 0 : if (conn)
3647 : {
3648 0 : closePGconn(conn);
3649 :
3650 0 : if (connectDBStart(conn) && connectDBComplete(conn))
3651 : {
3652 : /*
3653 : * Notify event procs of successful reset. We treat an event proc
3654 : * failure as disabling the connection ... good idea?
3655 : */
3656 : int i;
3657 :
3658 0 : for (i = 0; i < conn->nEvents; i++)
3659 : {
3660 : PGEventConnReset evt;
3661 :
3662 0 : evt.conn = conn;
3663 0 : if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
3664 0 : conn->events[i].passThrough))
3665 : {
3666 0 : conn->status = CONNECTION_BAD;
3667 0 : printfPQExpBuffer(&conn->errorMessage,
3668 : libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
3669 0 : conn->events[i].name);
3670 0 : break;
3671 : }
3672 : }
3673 : }
3674 : }
3675 0 : }
3676 :
3677 :
3678 : /*
3679 : * PQresetStart:
3680 : * resets the connection to the backend
3681 : * closes the existing connection and makes a new one
3682 : * Returns 1 on success, 0 on failure.
3683 : */
3684 : int
3685 0 : PQresetStart(PGconn *conn)
3686 : {
3687 0 : if (conn)
3688 : {
3689 0 : closePGconn(conn);
3690 :
3691 0 : return connectDBStart(conn);
3692 : }
3693 :
3694 0 : return 0;
3695 : }
3696 :
3697 :
3698 : /*
3699 : * PQresetPoll:
3700 : * resets the connection to the backend
3701 : * closes the existing connection and makes a new one
3702 : */
3703 : PostgresPollingStatusType
3704 0 : PQresetPoll(PGconn *conn)
3705 : {
3706 0 : if (conn)
3707 : {
3708 0 : PostgresPollingStatusType status = PQconnectPoll(conn);
3709 :
3710 0 : if (status == PGRES_POLLING_OK)
3711 : {
3712 : /*
3713 : * Notify event procs of successful reset. We treat an event proc
3714 : * failure as disabling the connection ... good idea?
3715 : */
3716 : int i;
3717 :
3718 0 : for (i = 0; i < conn->nEvents; i++)
3719 : {
3720 : PGEventConnReset evt;
3721 :
3722 0 : evt.conn = conn;
3723 0 : if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
3724 0 : conn->events[i].passThrough))
3725 : {
3726 0 : conn->status = CONNECTION_BAD;
3727 0 : printfPQExpBuffer(&conn->errorMessage,
3728 : libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
3729 0 : conn->events[i].name);
3730 0 : return PGRES_POLLING_FAILED;
3731 : }
3732 : }
3733 : }
3734 :
3735 0 : return status;
3736 : }
3737 :
3738 0 : return PGRES_POLLING_FAILED;
3739 : }
3740 :
3741 : /*
3742 : * PQgetCancel: get a PGcancel structure corresponding to a connection.
3743 : *
3744 : * A copy is needed to be able to cancel a running query from a different
3745 : * thread. If the same structure is used all structure members would have
3746 : * to be individually locked (if the entire structure was locked, it would
3747 : * be impossible to cancel a synchronous query because the structure would
3748 : * have to stay locked for the duration of the query).
3749 : */
3750 : PGcancel *
3751 26564 : PQgetCancel(PGconn *conn)
3752 : {
3753 : PGcancel *cancel;
3754 :
3755 26564 : if (!conn)
3756 0 : return NULL;
3757 :
3758 26564 : if (conn->sock == PGINVALID_SOCKET)
3759 0 : return NULL;
3760 :
3761 26564 : cancel = malloc(sizeof(PGcancel));
3762 26564 : if (cancel == NULL)
3763 0 : return NULL;
3764 :
3765 26564 : memcpy(&cancel->raddr, &conn->raddr, sizeof(SockAddr));
3766 26564 : cancel->be_pid = conn->be_pid;
3767 26564 : cancel->be_key = conn->be_key;
3768 :
3769 26564 : return cancel;
3770 : }
3771 :
3772 : /* PQfreeCancel: free a cancel structure */
3773 : void
3774 26564 : PQfreeCancel(PGcancel *cancel)
3775 : {
3776 26564 : if (cancel)
3777 26564 : free(cancel);
3778 26564 : }
3779 :
3780 :
3781 : /*
3782 : * PQcancel and PQrequestCancel: attempt to request cancellation of the
3783 : * current operation.
3784 : *
3785 : * The return value is TRUE if the cancel request was successfully
3786 : * dispatched, FALSE if not (in which case an error message is available).
3787 : * Note: successful dispatch is no guarantee that there will be any effect at
3788 : * the backend. The application must read the operation result as usual.
3789 : *
3790 : * CAUTION: we want this routine to be safely callable from a signal handler
3791 : * (for example, an application might want to call it in a SIGINT handler).
3792 : * This means we cannot use any C library routine that might be non-reentrant.
3793 : * malloc/free are often non-reentrant, and anything that might call them is
3794 : * just as dangerous. We avoid sprintf here for that reason. Building up
3795 : * error messages with strcpy/strcat is tedious but should be quite safe.
3796 : * We also save/restore errno in case the signal handler support doesn't.
3797 : *
3798 : * internal_cancel() is an internal helper function to make code-sharing
3799 : * between the two versions of the cancel function possible.
3800 : */
3801 : static int
3802 0 : internal_cancel(SockAddr *raddr, int be_pid, int be_key,
3803 : char *errbuf, int errbufsize)
3804 : {
3805 0 : int save_errno = SOCK_ERRNO;
3806 0 : pgsocket tmpsock = PGINVALID_SOCKET;
3807 : char sebuf[256];
3808 : int maxlen;
3809 : struct
3810 : {
3811 : uint32 packetlen;
3812 : CancelRequestPacket cp;
3813 : } crp;
3814 :
3815 : /*
3816 : * We need to open a temporary connection to the postmaster. Do this with
3817 : * only kernel calls.
3818 : */
3819 0 : if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
3820 : {
3821 0 : strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
3822 0 : goto cancel_errReturn;
3823 : }
3824 : retry3:
3825 0 : if (connect(tmpsock, (struct sockaddr *) &raddr->addr,
3826 : raddr->salen) < 0)
3827 : {
3828 0 : if (SOCK_ERRNO == EINTR)
3829 : /* Interrupted system call - we'll just try again */
3830 0 : goto retry3;
3831 0 : strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
3832 0 : goto cancel_errReturn;
3833 : }
3834 :
3835 : /*
3836 : * We needn't set nonblocking I/O or NODELAY options here.
3837 : */
3838 :
3839 : /* Create and send the cancel request packet. */
3840 :
3841 0 : crp.packetlen = htonl((uint32) sizeof(crp));
3842 0 : crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
3843 0 : crp.cp.backendPID = htonl(be_pid);
3844 0 : crp.cp.cancelAuthCode = htonl(be_key);
3845 :
3846 : retry4:
3847 0 : if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
3848 : {
3849 0 : if (SOCK_ERRNO == EINTR)
3850 : /* Interrupted system call - we'll just try again */
3851 0 : goto retry4;
3852 0 : strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
3853 0 : goto cancel_errReturn;
3854 : }
3855 :
3856 : /*
3857 : * Wait for the postmaster to close the connection, which indicates that
3858 : * it's processed the request. Without this delay, we might issue another
3859 : * command only to find that our cancel zaps that command instead of the
3860 : * one we thought we were canceling. Note we don't actually expect this
3861 : * read to obtain any data, we are just waiting for EOF to be signaled.
3862 : */
3863 : retry5:
3864 0 : if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
3865 : {
3866 0 : if (SOCK_ERRNO == EINTR)
3867 : /* Interrupted system call - we'll just try again */
3868 0 : goto retry5;
3869 : /* we ignore other error conditions */
3870 : }
3871 :
3872 : /* All done */
3873 0 : closesocket(tmpsock);
3874 0 : SOCK_ERRNO_SET(save_errno);
3875 0 : return TRUE;
3876 :
3877 : cancel_errReturn:
3878 :
3879 : /*
3880 : * Make sure we don't overflow the error buffer. Leave space for the \n at
3881 : * the end, and for the terminating zero.
3882 : */
3883 0 : maxlen = errbufsize - strlen(errbuf) - 2;
3884 0 : if (maxlen >= 0)
3885 : {
3886 0 : strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
3887 : maxlen);
3888 0 : strcat(errbuf, "\n");
3889 : }
3890 0 : if (tmpsock != PGINVALID_SOCKET)
3891 0 : closesocket(tmpsock);
3892 0 : SOCK_ERRNO_SET(save_errno);
3893 0 : return FALSE;
3894 : }
3895 :
3896 : /*
3897 : * PQcancel: request query cancel
3898 : *
3899 : * Returns TRUE if able to send the cancel request, FALSE if not.
3900 : *
3901 : * On failure, an error message is stored in *errbuf, which must be of size
3902 : * errbufsize (recommended size is 256 bytes). *errbuf is not changed on
3903 : * success return.
3904 : */
3905 : int
3906 0 : PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
3907 : {
3908 0 : if (!cancel)
3909 : {
3910 0 : strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
3911 0 : return FALSE;
3912 : }
3913 :
3914 0 : return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
3915 : errbuf, errbufsize);
3916 : }
3917 :
3918 : /*
3919 : * PQrequestCancel: old, not thread-safe function for requesting query cancel
3920 : *
3921 : * Returns TRUE if able to send the cancel request, FALSE if not.
3922 : *
3923 : * On failure, the error message is saved in conn->errorMessage; this means
3924 : * that this can't be used when there might be other active operations on
3925 : * the connection object.
3926 : *
3927 : * NOTE: error messages will be cut off at the current size of the
3928 : * error message buffer, since we dare not try to expand conn->errorMessage!
3929 : */
3930 : int
3931 0 : PQrequestCancel(PGconn *conn)
3932 : {
3933 : int r;
3934 :
3935 : /* Check we have an open connection */
3936 0 : if (!conn)
3937 0 : return FALSE;
3938 :
3939 0 : if (conn->sock == PGINVALID_SOCKET)
3940 : {
3941 0 : strlcpy(conn->errorMessage.data,
3942 : "PQrequestCancel() -- connection is not open\n",
3943 : conn->errorMessage.maxlen);
3944 0 : conn->errorMessage.len = strlen(conn->errorMessage.data);
3945 :
3946 0 : return FALSE;
3947 : }
3948 :
3949 0 : r = internal_cancel(&conn->raddr, conn->be_pid, conn->be_key,
3950 0 : conn->errorMessage.data, conn->errorMessage.maxlen);
3951 :
3952 0 : if (!r)
3953 0 : conn->errorMessage.len = strlen(conn->errorMessage.data);
3954 :
3955 0 : return r;
3956 : }
3957 :
3958 :
3959 : /*
3960 : * pqPacketSend() -- convenience routine to send a message to server.
3961 : *
3962 : * pack_type: the single-byte message type code. (Pass zero for startup
3963 : * packets, which have no message type code.)
3964 : *
3965 : * buf, buf_len: contents of message. The given length includes only what
3966 : * is in buf; the message type and message length fields are added here.
3967 : *
3968 : * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
3969 : * SIDE_EFFECTS: may block.
3970 : *
3971 : * Note: all messages sent with this routine have a length word, whether
3972 : * it's protocol 2.0 or 3.0.
3973 : */
3974 : int
3975 215 : pqPacketSend(PGconn *conn, char pack_type,
3976 : const void *buf, size_t buf_len)
3977 : {
3978 : /* Start the message. */
3979 215 : if (pqPutMsgStart(pack_type, true, conn))
3980 0 : return STATUS_ERROR;
3981 :
3982 : /* Send the message body. */
3983 215 : if (pqPutnchar(buf, buf_len, conn))
3984 0 : return STATUS_ERROR;
3985 :
3986 : /* Finish the message. */
3987 215 : if (pqPutMsgEnd(conn))
3988 0 : return STATUS_ERROR;
3989 :
3990 : /* Flush to ensure backend gets it. */
3991 215 : if (pqFlush(conn))
3992 0 : return STATUS_ERROR;
3993 :
3994 215 : return STATUS_OK;
3995 : }
3996 :
3997 : #ifdef USE_LDAP
3998 :
3999 : #define LDAP_URL "ldap://"
4000 : #define LDAP_DEF_PORT 389
4001 : #define PGLDAP_TIMEOUT 2
4002 :
4003 : #define ld_is_sp_tab(x) ((x) == ' ' || (x) == '\t')
4004 : #define ld_is_nl_cr(x) ((x) == '\r' || (x) == '\n')
4005 :
4006 :
4007 : /*
4008 : * ldapServiceLookup
4009 : *
4010 : * Search the LDAP URL passed as first argument, treat the result as a
4011 : * string of connection options that are parsed and added to the array of
4012 : * options passed as second argument.
4013 : *
4014 : * LDAP URLs must conform to RFC 1959 without escape sequences.
4015 : * ldap://host:port/dn?attributes?scope?filter?extensions
4016 : *
4017 : * Returns
4018 : * 0 if the lookup was successful,
4019 : * 1 if the connection to the LDAP server could be established but
4020 : * the search was unsuccessful,
4021 : * 2 if a connection could not be established, and
4022 : * 3 if a fatal error occurred.
4023 : *
4024 : * An error message is returned in the third argument for return codes 1 and 3.
4025 : */
4026 : static int
4027 : ldapServiceLookup(const char *purl, PQconninfoOption *options,
4028 : PQExpBuffer errorMessage)
4029 : {
4030 : int port = LDAP_DEF_PORT,
4031 : scope,
4032 : rc,
4033 : size,
4034 : state,
4035 : oldstate,
4036 : i;
4037 : #ifndef WIN32
4038 : int msgid;
4039 : #endif
4040 : bool found_keyword;
4041 : char *url,
4042 : *hostname,
4043 : *portstr,
4044 : *endptr,
4045 : *dn,
4046 : *scopestr,
4047 : *filter,
4048 : *result,
4049 : *p,
4050 : *p1 = NULL,
4051 : *optname = NULL,
4052 : *optval = NULL;
4053 : char *attrs[2] = {NULL, NULL};
4054 : LDAP *ld = NULL;
4055 : LDAPMessage *res,
4056 : *entry;
4057 : struct berval **values;
4058 : LDAP_TIMEVAL time = {PGLDAP_TIMEOUT, 0};
4059 :
4060 : if ((url = strdup(purl)) == NULL)
4061 : {
4062 : printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
4063 : return 3;
4064 : }
4065 :
4066 : /*
4067 : * Parse URL components, check for correctness. Basically, url has '\0'
4068 : * placed at component boundaries and variables are pointed at each
4069 : * component.
4070 : */
4071 :
4072 : if (pg_strncasecmp(url, LDAP_URL, strlen(LDAP_URL)) != 0)
4073 : {
4074 : printfPQExpBuffer(errorMessage,
4075 : libpq_gettext("invalid LDAP URL \"%s\": scheme must be ldap://\n"), purl);
4076 : free(url);
4077 : return 3;
4078 : }
4079 :
4080 : /* hostname */
4081 : hostname = url + strlen(LDAP_URL);
4082 : if (*hostname == '/') /* no hostname? */
4083 : hostname = DefaultHost; /* the default */
4084 :
4085 : /* dn, "distinguished name" */
4086 : p = strchr(url + strlen(LDAP_URL), '/');
4087 : if (p == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4088 : {
4089 : printfPQExpBuffer(errorMessage, libpq_gettext(
4090 : "invalid LDAP URL \"%s\": missing distinguished name\n"), purl);
4091 : free(url);
4092 : return 3;
4093 : }
4094 : *p = '\0'; /* terminate hostname */
4095 : dn = p + 1;
4096 :
4097 : /* attribute */
4098 : if ((p = strchr(dn, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4099 : {
4100 : printfPQExpBuffer(errorMessage, libpq_gettext(
4101 : "invalid LDAP URL \"%s\": must have exactly one attribute\n"), purl);
4102 : free(url);
4103 : return 3;
4104 : }
4105 : *p = '\0';
4106 : attrs[0] = p + 1;
4107 :
4108 : /* scope */
4109 : if ((p = strchr(attrs[0], '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4110 : {
4111 : printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
4112 : free(url);
4113 : return 3;
4114 : }
4115 : *p = '\0';
4116 : scopestr = p + 1;
4117 :
4118 : /* filter */
4119 : if ((p = strchr(scopestr, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4120 : {
4121 : printfPQExpBuffer(errorMessage,
4122 : libpq_gettext("invalid LDAP URL \"%s\": no filter\n"), purl);
4123 : free(url);
4124 : return 3;
4125 : }
4126 : *p = '\0';
4127 : filter = p + 1;
4128 : if ((p = strchr(filter, '?')) != NULL)
4129 : *p = '\0';
4130 :
4131 : /* port number? */
4132 : if ((p1 = strchr(hostname, ':')) != NULL)
4133 : {
4134 : long lport;
4135 :
4136 : *p1 = '\0';
4137 : portstr = p1 + 1;
4138 : errno = 0;
4139 : lport = strtol(portstr, &endptr, 10);
4140 : if (*portstr == '\0' || *endptr != '\0' || errno || lport < 0 || lport > 65535)
4141 : {
4142 : printfPQExpBuffer(errorMessage, libpq_gettext(
4143 : "invalid LDAP URL \"%s\": invalid port number\n"), purl);
4144 : free(url);
4145 : return 3;
4146 : }
4147 : port = (int) lport;
4148 : }
4149 :
4150 : /* Allow only one attribute */
4151 : if (strchr(attrs[0], ',') != NULL)
4152 : {
4153 : printfPQExpBuffer(errorMessage, libpq_gettext(
4154 : "invalid LDAP URL \"%s\": must have exactly one attribute\n"), purl);
4155 : free(url);
4156 : return 3;
4157 : }
4158 :
4159 : /* set scope */
4160 : if (pg_strcasecmp(scopestr, "base") == 0)
4161 : scope = LDAP_SCOPE_BASE;
4162 : else if (pg_strcasecmp(scopestr, "one") == 0)
4163 : scope = LDAP_SCOPE_ONELEVEL;
4164 : else if (pg_strcasecmp(scopestr, "sub") == 0)
4165 : scope = LDAP_SCOPE_SUBTREE;
4166 : else
4167 : {
4168 : printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
4169 : free(url);
4170 : return 3;
4171 : }
4172 :
4173 : /* initialize LDAP structure */
4174 : if ((ld = ldap_init(hostname, port)) == NULL)
4175 : {
4176 : printfPQExpBuffer(errorMessage,
4177 : libpq_gettext("could not create LDAP structure\n"));
4178 : free(url);
4179 : return 3;
4180 : }
4181 :
4182 : /*
4183 : * Perform an explicit anonymous bind.
4184 : *
4185 : * LDAP does not require that an anonymous bind is performed explicitly,
4186 : * but we want to distinguish between the case where LDAP bind does not
4187 : * succeed within PGLDAP_TIMEOUT seconds (return 2 to continue parsing the
4188 : * service control file) and the case where querying the LDAP server fails
4189 : * (return 1 to end parsing).
4190 : *
4191 : * Unfortunately there is no way of setting a timeout that works for both
4192 : * Windows and OpenLDAP.
4193 : */
4194 : #ifdef WIN32
4195 : /* the nonstandard ldap_connect function performs an anonymous bind */
4196 : if (ldap_connect(ld, &time) != LDAP_SUCCESS)
4197 : {
4198 : /* error or timeout in ldap_connect */
4199 : free(url);
4200 : ldap_unbind(ld);
4201 : return 2;
4202 : }
4203 : #else /* !WIN32 */
4204 : /* in OpenLDAP, use the LDAP_OPT_NETWORK_TIMEOUT option */
4205 : if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
4206 : {
4207 : free(url);
4208 : ldap_unbind(ld);
4209 : return 3;
4210 : }
4211 :
4212 : /* anonymous bind */
4213 : if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1)
4214 : {
4215 : /* error or network timeout */
4216 : free(url);
4217 : ldap_unbind(ld);
4218 : return 2;
4219 : }
4220 :
4221 : /* wait some time for the connection to succeed */
4222 : res = NULL;
4223 : if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &res)) == -1 ||
4224 : res == NULL)
4225 : {
4226 : /* error or timeout */
4227 : if (res != NULL)
4228 : ldap_msgfree(res);
4229 : free(url);
4230 : ldap_unbind(ld);
4231 : return 2;
4232 : }
4233 : ldap_msgfree(res);
4234 :
4235 : /* reset timeout */
4236 : time.tv_sec = -1;
4237 : if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
4238 : {
4239 : free(url);
4240 : ldap_unbind(ld);
4241 : return 3;
4242 : }
4243 : #endif /* WIN32 */
4244 :
4245 : /* search */
4246 : res = NULL;
4247 : if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &res))
4248 : != LDAP_SUCCESS)
4249 : {
4250 : if (res != NULL)
4251 : ldap_msgfree(res);
4252 : printfPQExpBuffer(errorMessage,
4253 : libpq_gettext("lookup on LDAP server failed: %s\n"),
4254 : ldap_err2string(rc));
4255 : ldap_unbind(ld);
4256 : free(url);
4257 : return 1;
4258 : }
4259 :
4260 : /* complain if there was not exactly one result */
4261 : if ((rc = ldap_count_entries(ld, res)) != 1)
4262 : {
4263 : printfPQExpBuffer(errorMessage,
4264 : rc ? libpq_gettext("more than one entry found on LDAP lookup\n")
4265 : : libpq_gettext("no entry found on LDAP lookup\n"));
4266 : ldap_msgfree(res);
4267 : ldap_unbind(ld);
4268 : free(url);
4269 : return 1;
4270 : }
4271 :
4272 : /* get entry */
4273 : if ((entry = ldap_first_entry(ld, res)) == NULL)
4274 : {
4275 : /* should never happen */
4276 : printfPQExpBuffer(errorMessage,
4277 : libpq_gettext("no entry found on LDAP lookup\n"));
4278 : ldap_msgfree(res);
4279 : ldap_unbind(ld);
4280 : free(url);
4281 : return 1;
4282 : }
4283 :
4284 : /* get values */
4285 : if ((values = ldap_get_values_len(ld, entry, attrs[0])) == NULL)
4286 : {
4287 : printfPQExpBuffer(errorMessage,
4288 : libpq_gettext("attribute has no values on LDAP lookup\n"));
4289 : ldap_msgfree(res);
4290 : ldap_unbind(ld);
4291 : free(url);
4292 : return 1;
4293 : }
4294 :
4295 : ldap_msgfree(res);
4296 : free(url);
4297 :
4298 : if (values[0] == NULL)
4299 : {
4300 : printfPQExpBuffer(errorMessage,
4301 : libpq_gettext("attribute has no values on LDAP lookup\n"));
4302 : ldap_value_free_len(values);
4303 : ldap_unbind(ld);
4304 : return 1;
4305 : }
4306 :
4307 : /* concatenate values into a single string with newline terminators */
4308 : size = 1; /* for the trailing null */
4309 : for (i = 0; values[i] != NULL; i++)
4310 : size += values[i]->bv_len + 1;
4311 : if ((result = malloc(size)) == NULL)
4312 : {
4313 : printfPQExpBuffer(errorMessage,
4314 : libpq_gettext("out of memory\n"));
4315 : ldap_value_free_len(values);
4316 : ldap_unbind(ld);
4317 : return 3;
4318 : }
4319 : p = result;
4320 : for (i = 0; values[i] != NULL; i++)
4321 : {
4322 : memcpy(p, values[i]->bv_val, values[i]->bv_len);
4323 : p += values[i]->bv_len;
4324 : *(p++) = '\n';
4325 : }
4326 : *p = '\0';
4327 :
4328 : ldap_value_free_len(values);
4329 : ldap_unbind(ld);
4330 :
4331 : /* parse result string */
4332 : oldstate = state = 0;
4333 : for (p = result; *p != '\0'; ++p)
4334 : {
4335 : switch (state)
4336 : {
4337 : case 0: /* between entries */
4338 : if (!ld_is_sp_tab(*p) && !ld_is_nl_cr(*p))
4339 : {
4340 : optname = p;
4341 : state = 1;
4342 : }
4343 : break;
4344 : case 1: /* in option name */
4345 : if (ld_is_sp_tab(*p))
4346 : {
4347 : *p = '\0';
4348 : state = 2;
4349 : }
4350 : else if (ld_is_nl_cr(*p))
4351 : {
4352 : printfPQExpBuffer(errorMessage, libpq_gettext(
4353 : "missing \"=\" after \"%s\" in connection info string\n"),
4354 : optname);
4355 : free(result);
4356 : return 3;
4357 : }
4358 : else if (*p == '=')
4359 : {
4360 : *p = '\0';
4361 : state = 3;
4362 : }
4363 : break;
4364 : case 2: /* after option name */
4365 : if (*p == '=')
4366 : {
4367 : state = 3;
4368 : }
4369 : else if (!ld_is_sp_tab(*p))
4370 : {
4371 : printfPQExpBuffer(errorMessage, libpq_gettext(
4372 : "missing \"=\" after \"%s\" in connection info string\n"),
4373 : optname);
4374 : free(result);
4375 : return 3;
4376 : }
4377 : break;
4378 : case 3: /* before option value */
4379 : if (*p == '\'')
4380 : {
4381 : optval = p + 1;
4382 : p1 = p + 1;
4383 : state = 5;
4384 : }
4385 : else if (ld_is_nl_cr(*p))
4386 : {
4387 : optval = optname + strlen(optname); /* empty */
4388 : state = 0;
4389 : }
4390 : else if (!ld_is_sp_tab(*p))
4391 : {
4392 : optval = p;
4393 : state = 4;
4394 : }
4395 : break;
4396 : case 4: /* in unquoted option value */
4397 : if (ld_is_sp_tab(*p) || ld_is_nl_cr(*p))
4398 : {
4399 : *p = '\0';
4400 : state = 0;
4401 : }
4402 : break;
4403 : case 5: /* in quoted option value */
4404 : if (*p == '\'')
4405 : {
4406 : *p1 = '\0';
4407 : state = 0;
4408 : }
4409 : else if (*p == '\\')
4410 : state = 6;
4411 : else
4412 : *(p1++) = *p;
4413 : break;
4414 : case 6: /* in quoted option value after escape */
4415 : *(p1++) = *p;
4416 : state = 5;
4417 : break;
4418 : }
4419 :
4420 : if (state == 0 && oldstate != 0)
4421 : {
4422 : found_keyword = false;
4423 : for (i = 0; options[i].keyword; i++)
4424 : {
4425 : if (strcmp(options[i].keyword, optname) == 0)
4426 : {
4427 : if (options[i].val == NULL)
4428 : {
4429 : options[i].val = strdup(optval);
4430 : if (!options[i].val)
4431 : {
4432 : printfPQExpBuffer(errorMessage,
4433 : libpq_gettext("out of memory\n"));
4434 : free(result);
4435 : return 3;
4436 : }
4437 : }
4438 : found_keyword = true;
4439 : break;
4440 : }
4441 : }
4442 : if (!found_keyword)
4443 : {
4444 : printfPQExpBuffer(errorMessage,
4445 : libpq_gettext("invalid connection option \"%s\"\n"),
4446 : optname);
4447 : free(result);
4448 : return 1;
4449 : }
4450 : optname = NULL;
4451 : optval = NULL;
4452 : }
4453 : oldstate = state;
4454 : }
4455 :
4456 : free(result);
4457 :
4458 : if (state == 5 || state == 6)
4459 : {
4460 : printfPQExpBuffer(errorMessage, libpq_gettext(
4461 : "unterminated quoted string in connection info string\n"));
4462 : return 3;
4463 : }
4464 :
4465 : return 0;
4466 : }
4467 :
4468 : #endif /* USE_LDAP */
4469 :
4470 : #define MAXBUFSIZE 256
4471 :
4472 : static int
4473 217 : parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
4474 : {
4475 217 : const char *service = conninfo_getval(options, "service");
4476 : char serviceFile[MAXPGPATH];
4477 : char *env;
4478 217 : bool group_found = false;
4479 : int status;
4480 : struct stat stat_buf;
4481 :
4482 : /*
4483 : * We have to special-case the environment variable PGSERVICE here, since
4484 : * this is and should be called before inserting environment defaults for
4485 : * other connection options.
4486 : */
4487 217 : if (service == NULL)
4488 217 : service = getenv("PGSERVICE");
4489 :
4490 217 : if (service == NULL)
4491 217 : return 0;
4492 :
4493 0 : if ((env = getenv("PGSERVICEFILE")) != NULL)
4494 0 : strlcpy(serviceFile, env, sizeof(serviceFile));
4495 : else
4496 : {
4497 : char homedir[MAXPGPATH];
4498 :
4499 0 : if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
4500 : {
4501 0 : printfPQExpBuffer(errorMessage, libpq_gettext("could not get home directory to locate service definition file"));
4502 0 : return 1;
4503 : }
4504 0 : snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
4505 0 : errno = 0;
4506 0 : if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4507 0 : goto next_file;
4508 : }
4509 :
4510 0 : status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4511 0 : if (group_found || status != 0)
4512 0 : return status;
4513 :
4514 : next_file:
4515 :
4516 : /*
4517 : * This could be used by any application so we can't use the binary
4518 : * location to find our config files.
4519 : */
4520 0 : snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
4521 0 : getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
4522 0 : errno = 0;
4523 0 : if (stat(serviceFile, &stat_buf) != 0 && errno == ENOENT)
4524 0 : goto last_file;
4525 :
4526 0 : status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4527 0 : if (status != 0)
4528 0 : return status;
4529 :
4530 : last_file:
4531 0 : if (!group_found)
4532 : {
4533 0 : printfPQExpBuffer(errorMessage,
4534 : libpq_gettext("definition of service \"%s\" not found\n"), service);
4535 0 : return 3;
4536 : }
4537 :
4538 0 : return 0;
4539 : }
4540 :
4541 : static int
4542 0 : parseServiceFile(const char *serviceFile,
4543 : const char *service,
4544 : PQconninfoOption *options,
4545 : PQExpBuffer errorMessage,
4546 : bool *group_found)
4547 : {
4548 0 : int linenr = 0,
4549 : i;
4550 : FILE *f;
4551 : char buf[MAXBUFSIZE],
4552 : *line;
4553 :
4554 0 : f = fopen(serviceFile, "r");
4555 0 : if (f == NULL)
4556 : {
4557 0 : printfPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
4558 : serviceFile);
4559 0 : return 1;
4560 : }
4561 :
4562 0 : while ((line = fgets(buf, sizeof(buf), f)) != NULL)
4563 : {
4564 0 : linenr++;
4565 :
4566 0 : if (strlen(line) >= sizeof(buf) - 1)
4567 : {
4568 0 : fclose(f);
4569 0 : printfPQExpBuffer(errorMessage,
4570 : libpq_gettext("line %d too long in service file \"%s\"\n"),
4571 : linenr,
4572 : serviceFile);
4573 0 : return 2;
4574 : }
4575 :
4576 : /* ignore EOL at end of line */
4577 0 : if (strlen(line) && line[strlen(line) - 1] == '\n')
4578 0 : line[strlen(line) - 1] = 0;
4579 :
4580 : /* ignore leading blanks */
4581 0 : while (*line && isspace((unsigned char) line[0]))
4582 0 : line++;
4583 :
4584 : /* ignore comments and empty lines */
4585 0 : if (strlen(line) == 0 || line[0] == '#')
4586 0 : continue;
4587 :
4588 : /* Check for right groupname */
4589 0 : if (line[0] == '[')
4590 : {
4591 0 : if (*group_found)
4592 : {
4593 : /* group info already read */
4594 0 : fclose(f);
4595 0 : return 0;
4596 : }
4597 :
4598 0 : if (strncmp(line + 1, service, strlen(service)) == 0 &&
4599 0 : line[strlen(service) + 1] == ']')
4600 0 : *group_found = true;
4601 : else
4602 0 : *group_found = false;
4603 : }
4604 : else
4605 : {
4606 0 : if (*group_found)
4607 : {
4608 : /*
4609 : * Finally, we are in the right group and can parse the line
4610 : */
4611 : char *key,
4612 : *val;
4613 : bool found_keyword;
4614 :
4615 : #ifdef USE_LDAP
4616 : if (strncmp(line, "ldap", 4) == 0)
4617 : {
4618 : int rc = ldapServiceLookup(line, options, errorMessage);
4619 :
4620 : /* if rc = 2, go on reading for fallback */
4621 : switch (rc)
4622 : {
4623 : case 0:
4624 : fclose(f);
4625 : return 0;
4626 : case 1:
4627 : case 3:
4628 : fclose(f);
4629 : return 3;
4630 : case 2:
4631 : continue;
4632 : }
4633 : }
4634 : #endif
4635 :
4636 0 : key = line;
4637 0 : val = strchr(line, '=');
4638 0 : if (val == NULL)
4639 : {
4640 0 : printfPQExpBuffer(errorMessage,
4641 : libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4642 : serviceFile,
4643 : linenr);
4644 0 : fclose(f);
4645 0 : return 3;
4646 : }
4647 0 : *val++ = '\0';
4648 :
4649 0 : if (strcmp(key, "service") == 0)
4650 : {
4651 0 : printfPQExpBuffer(errorMessage,
4652 : libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
4653 : serviceFile,
4654 : linenr);
4655 0 : fclose(f);
4656 0 : return 3;
4657 : }
4658 :
4659 : /*
4660 : * Set the parameter --- but don't override any previous
4661 : * explicit setting.
4662 : */
4663 0 : found_keyword = false;
4664 0 : for (i = 0; options[i].keyword; i++)
4665 : {
4666 0 : if (strcmp(options[i].keyword, key) == 0)
4667 : {
4668 0 : if (options[i].val == NULL)
4669 0 : options[i].val = strdup(val);
4670 0 : if (!options[i].val)
4671 : {
4672 0 : printfPQExpBuffer(errorMessage,
4673 : libpq_gettext("out of memory\n"));
4674 0 : fclose(f);
4675 0 : return 3;
4676 : }
4677 0 : found_keyword = true;
4678 0 : break;
4679 : }
4680 : }
4681 :
4682 0 : if (!found_keyword)
4683 : {
4684 0 : printfPQExpBuffer(errorMessage,
4685 : libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4686 : serviceFile,
4687 : linenr);
4688 0 : fclose(f);
4689 0 : return 3;
4690 : }
4691 : }
4692 : }
4693 : }
4694 :
4695 0 : fclose(f);
4696 :
4697 0 : return 0;
4698 : }
4699 :
4700 :
4701 : /*
4702 : * PQconninfoParse
4703 : *
4704 : * Parse a string like PQconnectdb() would do and return the
4705 : * resulting connection options array. NULL is returned on failure.
4706 : * The result contains only options specified directly in the string,
4707 : * not any possible default values.
4708 : *
4709 : * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd
4710 : * string on failure (use PQfreemem to free it). In out-of-memory conditions
4711 : * both *errmsg and the result could be NULL.
4712 : *
4713 : * NOTE: the returned array is dynamically allocated and should
4714 : * be freed when no longer needed via PQconninfoFree().
4715 : */
4716 : PQconninfoOption *
4717 7 : PQconninfoParse(const char *conninfo, char **errmsg)
4718 : {
4719 : PQExpBufferData errorBuf;
4720 : PQconninfoOption *connOptions;
4721 :
4722 7 : if (errmsg)
4723 7 : *errmsg = NULL; /* default */
4724 7 : initPQExpBuffer(&errorBuf);
4725 7 : if (PQExpBufferDataBroken(errorBuf))
4726 0 : return NULL; /* out of memory already :-( */
4727 7 : connOptions = parse_connection_string(conninfo, &errorBuf, false);
4728 7 : if (connOptions == NULL && errmsg)
4729 2 : *errmsg = errorBuf.data;
4730 : else
4731 5 : termPQExpBuffer(&errorBuf);
4732 7 : return connOptions;
4733 : }
4734 :
4735 : /*
4736 : * Build a working copy of the constant PQconninfoOptions array.
4737 : */
4738 : static PQconninfoOption *
4739 257 : conninfo_init(PQExpBuffer errorMessage)
4740 : {
4741 : PQconninfoOption *options;
4742 : PQconninfoOption *opt_dest;
4743 : const internalPQconninfoOption *cur_opt;
4744 :
4745 : /*
4746 : * Get enough memory for all options in PQconninfoOptions, even if some
4747 : * end up being filtered out.
4748 : */
4749 257 : options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4750 257 : if (options == NULL)
4751 : {
4752 0 : printfPQExpBuffer(errorMessage,
4753 : libpq_gettext("out of memory\n"));
4754 0 : return NULL;
4755 : }
4756 257 : opt_dest = options;
4757 :
4758 7453 : for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4759 : {
4760 : /* Only copy the public part of the struct, not the full internal */
4761 7196 : memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4762 7196 : opt_dest++;
4763 : }
4764 257 : MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4765 :
4766 257 : return options;
4767 : }
4768 :
4769 : /*
4770 : * Connection string parser
4771 : *
4772 : * Returns a malloc'd PQconninfoOption array, if parsing is successful.
4773 : * Otherwise, NULL is returned and an error message is left in errorMessage.
4774 : *
4775 : * If use_defaults is TRUE, default values are filled in (from a service file,
4776 : * environment variables, etc).
4777 : */
4778 : static PQconninfoOption *
4779 40 : parse_connection_string(const char *connstr, PQExpBuffer errorMessage,
4780 : bool use_defaults)
4781 : {
4782 : /* Parse as URI if connection string matches URI prefix */
4783 40 : if (uri_prefix_length(connstr) != 0)
4784 0 : return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4785 :
4786 : /* Parse as default otherwise */
4787 40 : return conninfo_parse(connstr, errorMessage, use_defaults);
4788 : }
4789 :
4790 : /*
4791 : * Checks if connection string starts with either of the valid URI prefix
4792 : * designators.
4793 : *
4794 : * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
4795 : *
4796 : * XXX this is duplicated in psql/common.c.
4797 : */
4798 : static int
4799 257 : uri_prefix_length(const char *connstr)
4800 : {
4801 257 : if (strncmp(connstr, uri_designator,
4802 : sizeof(uri_designator) - 1) == 0)
4803 0 : return sizeof(uri_designator) - 1;
4804 :
4805 257 : if (strncmp(connstr, short_uri_designator,
4806 : sizeof(short_uri_designator) - 1) == 0)
4807 0 : return sizeof(short_uri_designator) - 1;
4808 :
4809 257 : return 0;
4810 : }
4811 :
4812 : /*
4813 : * Recognized connection string either starts with a valid URI prefix or
4814 : * contains a "=" in it.
4815 : *
4816 : * Must be consistent with parse_connection_string: anything for which this
4817 : * returns true should at least look like it's parseable by that routine.
4818 : *
4819 : * XXX this is duplicated in psql/common.c
4820 : */
4821 : static bool
4822 217 : recognized_connection_string(const char *connstr)
4823 : {
4824 217 : return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
4825 : }
4826 :
4827 : /*
4828 : * Subroutine for parse_connection_string
4829 : *
4830 : * Deal with a string containing key=value pairs.
4831 : */
4832 : static PQconninfoOption *
4833 40 : conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
4834 : bool use_defaults)
4835 : {
4836 : char *pname;
4837 : char *pval;
4838 : char *buf;
4839 : char *cp;
4840 : char *cp2;
4841 : PQconninfoOption *options;
4842 :
4843 : /* Make a working copy of PQconninfoOptions */
4844 40 : options = conninfo_init(errorMessage);
4845 40 : if (options == NULL)
4846 0 : return NULL;
4847 :
4848 : /* Need a modifiable copy of the input string */
4849 40 : if ((buf = strdup(conninfo)) == NULL)
4850 : {
4851 0 : printfPQExpBuffer(errorMessage,
4852 : libpq_gettext("out of memory\n"));
4853 0 : PQconninfoFree(options);
4854 0 : return NULL;
4855 : }
4856 40 : cp = buf;
4857 :
4858 117 : while (*cp)
4859 : {
4860 : /* Skip blanks before the parameter name */
4861 39 : if (isspace((unsigned char) *cp))
4862 : {
4863 0 : cp++;
4864 0 : continue;
4865 : }
4866 :
4867 : /* Get the parameter name */
4868 39 : pname = cp;
4869 314 : while (*cp)
4870 : {
4871 273 : if (*cp == '=')
4872 37 : break;
4873 236 : if (isspace((unsigned char) *cp))
4874 : {
4875 0 : *cp++ = '\0';
4876 0 : while (*cp)
4877 : {
4878 0 : if (!isspace((unsigned char) *cp))
4879 0 : break;
4880 0 : cp++;
4881 : }
4882 0 : break;
4883 : }
4884 236 : cp++;
4885 : }
4886 :
4887 : /* Check that there is a following '=' */
4888 39 : if (*cp != '=')
4889 : {
4890 2 : printfPQExpBuffer(errorMessage,
4891 : libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
4892 : pname);
4893 2 : PQconninfoFree(options);
4894 2 : free(buf);
4895 2 : return NULL;
4896 : }
4897 37 : *cp++ = '\0';
4898 :
4899 : /* Skip blanks after the '=' */
4900 74 : while (*cp)
4901 : {
4902 37 : if (!isspace((unsigned char) *cp))
4903 37 : break;
4904 0 : cp++;
4905 : }
4906 :
4907 : /* Get the parameter value */
4908 37 : pval = cp;
4909 :
4910 37 : if (*cp != '\'')
4911 : {
4912 37 : cp2 = pval;
4913 453 : while (*cp)
4914 : {
4915 379 : if (isspace((unsigned char) *cp))
4916 : {
4917 0 : *cp++ = '\0';
4918 0 : break;
4919 : }
4920 379 : if (*cp == '\\')
4921 : {
4922 0 : cp++;
4923 0 : if (*cp != '\0')
4924 0 : *cp2++ = *cp++;
4925 : }
4926 : else
4927 379 : *cp2++ = *cp++;
4928 : }
4929 37 : *cp2 = '\0';
4930 : }
4931 : else
4932 : {
4933 0 : cp2 = pval;
4934 0 : cp++;
4935 : for (;;)
4936 : {
4937 0 : if (*cp == '\0')
4938 : {
4939 0 : printfPQExpBuffer(errorMessage,
4940 : libpq_gettext("unterminated quoted string in connection info string\n"));
4941 0 : PQconninfoFree(options);
4942 0 : free(buf);
4943 0 : return NULL;
4944 : }
4945 0 : if (*cp == '\\')
4946 : {
4947 0 : cp++;
4948 0 : if (*cp != '\0')
4949 0 : *cp2++ = *cp++;
4950 0 : continue;
4951 : }
4952 0 : if (*cp == '\'')
4953 : {
4954 0 : *cp2 = '\0';
4955 0 : cp++;
4956 0 : break;
4957 : }
4958 0 : *cp2++ = *cp++;
4959 0 : }
4960 : }
4961 :
4962 : /*
4963 : * Now that we have the name and the value, store the record.
4964 : */
4965 37 : if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
4966 : {
4967 0 : PQconninfoFree(options);
4968 0 : free(buf);
4969 0 : return NULL;
4970 : }
4971 : }
4972 :
4973 : /* Done with the modifiable input string */
4974 38 : free(buf);
4975 :
4976 : /*
4977 : * Add in defaults if the caller wants that.
4978 : */
4979 38 : if (use_defaults)
4980 : {
4981 0 : if (!conninfo_add_defaults(options, errorMessage))
4982 : {
4983 0 : PQconninfoFree(options);
4984 0 : return NULL;
4985 : }
4986 : }
4987 :
4988 38 : return options;
4989 : }
4990 :
4991 : /*
4992 : * Conninfo array parser routine
4993 : *
4994 : * If successful, a malloc'd PQconninfoOption array is returned.
4995 : * If not successful, NULL is returned and an error message is
4996 : * left in errorMessage.
4997 : * Defaults are supplied (from a service file, environment variables, etc)
4998 : * for unspecified options, but only if use_defaults is TRUE.
4999 : *
5000 : * If expand_dbname is non-zero, and the value passed for the first occurrence
5001 : * of "dbname" keyword is a connection string (as indicated by
5002 : * recognized_connection_string) then parse and process it, overriding any
5003 : * previously processed conflicting keywords. Subsequent keywords will take
5004 : * precedence, however. In-tree programs generally specify expand_dbname=true,
5005 : * so command-line arguments naming a database can use a connection string.
5006 : * Some code acquires arbitrary database names from known-literal sources like
5007 : * PQdb(), PQconninfoParse() and pg_database.datname. When connecting to such
5008 : * a database, in-tree code first wraps the name in a connection string.
5009 : */
5010 : static PQconninfoOption *
5011 217 : conninfo_array_parse(const char *const *keywords, const char *const *values,
5012 : PQExpBuffer errorMessage, bool use_defaults,
5013 : int expand_dbname)
5014 : {
5015 : PQconninfoOption *options;
5016 217 : PQconninfoOption *dbname_options = NULL;
5017 : PQconninfoOption *option;
5018 217 : int i = 0;
5019 :
5020 : /*
5021 : * If expand_dbname is non-zero, check keyword "dbname" to see if val is
5022 : * actually a recognized connection string.
5023 : */
5024 1269 : while (expand_dbname && keywords[i])
5025 : {
5026 1052 : const char *pname = keywords[i];
5027 1052 : const char *pvalue = values[i];
5028 :
5029 : /* first find "dbname" if any */
5030 1052 : if (strcmp(pname, "dbname") == 0 && pvalue)
5031 : {
5032 : /*
5033 : * If value is a connection string, parse it, but do not use
5034 : * defaults here -- those get picked up later. We only want to
5035 : * override for those parameters actually passed.
5036 : */
5037 217 : if (recognized_connection_string(pvalue))
5038 : {
5039 33 : dbname_options = parse_connection_string(pvalue, errorMessage, false);
5040 33 : if (dbname_options == NULL)
5041 0 : return NULL;
5042 : }
5043 217 : break;
5044 : }
5045 835 : ++i;
5046 : }
5047 :
5048 : /* Make a working copy of PQconninfoOptions */
5049 217 : options = conninfo_init(errorMessage);
5050 217 : if (options == NULL)
5051 : {
5052 0 : PQconninfoFree(dbname_options);
5053 0 : return NULL;
5054 : }
5055 :
5056 : /* Parse the keywords/values arrays */
5057 217 : i = 0;
5058 1953 : while (keywords[i])
5059 : {
5060 1519 : const char *pname = keywords[i];
5061 1519 : const char *pvalue = values[i];
5062 :
5063 1519 : if (pvalue != NULL && pvalue[0] != '\0')
5064 : {
5065 : /* Search for the param record */
5066 5489 : for (option = options; option->keyword != NULL; option++)
5067 : {
5068 5489 : if (strcmp(option->keyword, pname) == 0)
5069 535 : break;
5070 : }
5071 :
5072 : /* Check for invalid connection option */
5073 535 : if (option->keyword == NULL)
5074 : {
5075 0 : printfPQExpBuffer(errorMessage,
5076 : libpq_gettext("invalid connection option \"%s\"\n"),
5077 : pname);
5078 0 : PQconninfoFree(options);
5079 0 : PQconninfoFree(dbname_options);
5080 0 : return NULL;
5081 : }
5082 :
5083 : /*
5084 : * If we are on the first dbname parameter, and we have a parsed
5085 : * connection string, copy those parameters across, overriding any
5086 : * existing previous settings.
5087 : */
5088 535 : if (strcmp(pname, "dbname") == 0 && dbname_options)
5089 33 : {
5090 : PQconninfoOption *str_option;
5091 :
5092 957 : for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
5093 : {
5094 924 : if (str_option->val != NULL)
5095 : {
5096 : int k;
5097 :
5098 231 : for (k = 0; options[k].keyword; k++)
5099 : {
5100 231 : if (strcmp(options[k].keyword, str_option->keyword) == 0)
5101 : {
5102 33 : if (options[k].val)
5103 0 : free(options[k].val);
5104 33 : options[k].val = strdup(str_option->val);
5105 33 : if (!options[k].val)
5106 : {
5107 0 : printfPQExpBuffer(errorMessage,
5108 : libpq_gettext("out of memory\n"));
5109 0 : PQconninfoFree(options);
5110 0 : PQconninfoFree(dbname_options);
5111 0 : return NULL;
5112 : }
5113 33 : break;
5114 : }
5115 : }
5116 : }
5117 : }
5118 :
5119 : /*
5120 : * Forget the parsed connection string, so that any subsequent
5121 : * dbname parameters will not be expanded.
5122 : */
5123 33 : PQconninfoFree(dbname_options);
5124 33 : dbname_options = NULL;
5125 : }
5126 : else
5127 : {
5128 : /*
5129 : * Store the value, overriding previous settings
5130 : */
5131 502 : if (option->val)
5132 0 : free(option->val);
5133 502 : option->val = strdup(pvalue);
5134 502 : if (!option->val)
5135 : {
5136 0 : printfPQExpBuffer(errorMessage,
5137 : libpq_gettext("out of memory\n"));
5138 0 : PQconninfoFree(options);
5139 0 : PQconninfoFree(dbname_options);
5140 0 : return NULL;
5141 : }
5142 : }
5143 : }
5144 1519 : ++i;
5145 : }
5146 217 : PQconninfoFree(dbname_options);
5147 :
5148 : /*
5149 : * Add in defaults if the caller wants that.
5150 : */
5151 217 : if (use_defaults)
5152 : {
5153 217 : if (!conninfo_add_defaults(options, errorMessage))
5154 : {
5155 0 : PQconninfoFree(options);
5156 0 : return NULL;
5157 : }
5158 : }
5159 :
5160 217 : return options;
5161 : }
5162 :
5163 : /*
5164 : * Add the default values for any unspecified options to the connection
5165 : * options array.
5166 : *
5167 : * Defaults are obtained from a service file, environment variables, etc.
5168 : *
5169 : * Returns TRUE if successful, otherwise FALSE; errorMessage, if supplied,
5170 : * is filled in upon failure. Note that failure to locate a default value
5171 : * is not an error condition here --- we just leave the option's value as
5172 : * NULL.
5173 : */
5174 : static bool
5175 217 : conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
5176 : {
5177 : PQconninfoOption *option;
5178 : char *tmp;
5179 :
5180 : /*
5181 : * If there's a service spec, use it to obtain any not-explicitly-given
5182 : * parameters. Ignore error if no error message buffer is passed because
5183 : * there is no way to pass back the failure message.
5184 : */
5185 217 : if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5186 0 : return false;
5187 :
5188 : /*
5189 : * Get the fallback resources for parameters not specified in the conninfo
5190 : * string nor the service.
5191 : */
5192 6293 : for (option = options; option->keyword != NULL; option++)
5193 : {
5194 6076 : if (option->val != NULL)
5195 535 : continue; /* Value was in conninfo or service */
5196 :
5197 : /*
5198 : * Try to get the environment variable fallback
5199 : */
5200 5541 : if (option->envvar != NULL)
5201 : {
5202 4456 : if ((tmp = getenv(option->envvar)) != NULL)
5203 : {
5204 802 : option->val = strdup(tmp);
5205 802 : if (!option->val)
5206 : {
5207 0 : if (errorMessage)
5208 0 : printfPQExpBuffer(errorMessage,
5209 : libpq_gettext("out of memory\n"));
5210 0 : return false;
5211 : }
5212 802 : continue;
5213 : }
5214 : }
5215 :
5216 : /*
5217 : * Interpret the deprecated PGREQUIRESSL environment variable. Per
5218 : * tradition, translate values starting with "1" to sslmode=require,
5219 : * and ignore other values. Given both PGREQUIRESSL=1 and PGSSLMODE,
5220 : * PGSSLMODE takes precedence; the opposite was true before v9.3.
5221 : */
5222 4739 : if (strcmp(option->keyword, "sslmode") == 0)
5223 : {
5224 217 : const char *requiresslenv = getenv("PGREQUIRESSL");
5225 :
5226 217 : if (requiresslenv != NULL && requiresslenv[0] == '1')
5227 : {
5228 0 : option->val = strdup("require");
5229 0 : if (!option->val)
5230 : {
5231 0 : if (errorMessage)
5232 0 : printfPQExpBuffer(errorMessage,
5233 : libpq_gettext("out of memory\n"));
5234 0 : return false;
5235 : }
5236 0 : continue;
5237 : }
5238 : }
5239 :
5240 : /*
5241 : * No environment variable specified or the variable isn't set - try
5242 : * compiled-in default
5243 : */
5244 4739 : if (option->compiled != NULL)
5245 : {
5246 1085 : option->val = strdup(option->compiled);
5247 1085 : if (!option->val)
5248 : {
5249 0 : if (errorMessage)
5250 0 : printfPQExpBuffer(errorMessage,
5251 : libpq_gettext("out of memory\n"));
5252 0 : return false;
5253 : }
5254 1085 : continue;
5255 : }
5256 :
5257 : /*
5258 : * Special handling for "user" option. Note that if pg_fe_getauthname
5259 : * fails, we just leave the value as NULL; there's no need for this to
5260 : * be an error condition if the caller provides a user name. The only
5261 : * reason we do this now at all is so that callers of PQconndefaults
5262 : * will see a correct default (barring error, of course).
5263 : */
5264 3654 : if (strcmp(option->keyword, "user") == 0)
5265 : {
5266 184 : option->val = pg_fe_getauthname(NULL);
5267 184 : continue;
5268 : }
5269 : }
5270 :
5271 217 : return true;
5272 : }
5273 :
5274 : /*
5275 : * Subroutine for parse_connection_string
5276 : *
5277 : * Deal with a URI connection string.
5278 : */
5279 : static PQconninfoOption *
5280 0 : conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage,
5281 : bool use_defaults)
5282 : {
5283 : PQconninfoOption *options;
5284 :
5285 : /* Make a working copy of PQconninfoOptions */
5286 0 : options = conninfo_init(errorMessage);
5287 0 : if (options == NULL)
5288 0 : return NULL;
5289 :
5290 0 : if (!conninfo_uri_parse_options(options, uri, errorMessage))
5291 : {
5292 0 : PQconninfoFree(options);
5293 0 : return NULL;
5294 : }
5295 :
5296 : /*
5297 : * Add in defaults if the caller wants that.
5298 : */
5299 0 : if (use_defaults)
5300 : {
5301 0 : if (!conninfo_add_defaults(options, errorMessage))
5302 : {
5303 0 : PQconninfoFree(options);
5304 0 : return NULL;
5305 : }
5306 : }
5307 :
5308 0 : return options;
5309 : }
5310 :
5311 : /*
5312 : * conninfo_uri_parse_options
5313 : * Actual URI parser.
5314 : *
5315 : * If successful, returns true while the options array is filled with parsed
5316 : * options from the URI.
5317 : * If not successful, returns false and fills errorMessage accordingly.
5318 : *
5319 : * Parses the connection URI string in 'uri' according to the URI syntax (RFC
5320 : * 3986):
5321 : *
5322 : * postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
5323 : *
5324 : * where "netloc" is a hostname, an IPv4 address, or an IPv6 address surrounded
5325 : * by literal square brackets. As an extension, we also allow multiple
5326 : * netloc[:port] specifications, separated by commas:
5327 : *
5328 : * postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
5329 : *
5330 : * Any of the URI parts might use percent-encoding (%xy).
5331 : */
5332 : static bool
5333 0 : conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
5334 : PQExpBuffer errorMessage)
5335 : {
5336 : int prefix_len;
5337 : char *p;
5338 0 : char *buf = NULL;
5339 : char *start;
5340 0 : char prevchar = '\0';
5341 0 : char *user = NULL;
5342 0 : char *host = NULL;
5343 0 : bool retval = false;
5344 : PQExpBufferData hostbuf;
5345 : PQExpBufferData portbuf;
5346 :
5347 0 : initPQExpBuffer(&hostbuf);
5348 0 : initPQExpBuffer(&portbuf);
5349 0 : if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5350 : {
5351 0 : printfPQExpBuffer(errorMessage,
5352 : libpq_gettext("out of memory\n"));
5353 0 : goto cleanup;
5354 : }
5355 :
5356 : /* need a modifiable copy of the input URI */
5357 0 : buf = strdup(uri);
5358 0 : if (buf == NULL)
5359 : {
5360 0 : printfPQExpBuffer(errorMessage,
5361 : libpq_gettext("out of memory\n"));
5362 0 : goto cleanup;
5363 : }
5364 0 : start = buf;
5365 :
5366 : /* Skip the URI prefix */
5367 0 : prefix_len = uri_prefix_length(uri);
5368 0 : if (prefix_len == 0)
5369 : {
5370 : /* Should never happen */
5371 0 : printfPQExpBuffer(errorMessage,
5372 : libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
5373 : uri);
5374 0 : goto cleanup;
5375 : }
5376 0 : start += prefix_len;
5377 0 : p = start;
5378 :
5379 : /* Look ahead for possible user credentials designator */
5380 0 : while (*p && *p != '@' && *p != '/')
5381 0 : ++p;
5382 0 : if (*p == '@')
5383 : {
5384 : /*
5385 : * Found username/password designator, so URI should be of the form
5386 : * "scheme://user[:password]@[netloc]".
5387 : */
5388 0 : user = start;
5389 :
5390 0 : p = user;
5391 0 : while (*p != ':' && *p != '@')
5392 0 : ++p;
5393 :
5394 : /* Save last char and cut off at end of user name */
5395 0 : prevchar = *p;
5396 0 : *p = '\0';
5397 :
5398 0 : if (*user &&
5399 0 : !conninfo_storeval(options, "user", user,
5400 : errorMessage, false, true))
5401 0 : goto cleanup;
5402 :
5403 0 : if (prevchar == ':')
5404 : {
5405 0 : const char *password = p + 1;
5406 :
5407 0 : while (*p != '@')
5408 0 : ++p;
5409 0 : *p = '\0';
5410 :
5411 0 : if (*password &&
5412 0 : !conninfo_storeval(options, "password", password,
5413 : errorMessage, false, true))
5414 0 : goto cleanup;
5415 : }
5416 :
5417 : /* Advance past end of parsed user name or password token */
5418 0 : ++p;
5419 : }
5420 : else
5421 : {
5422 : /*
5423 : * No username/password designator found. Reset to start of URI.
5424 : */
5425 0 : p = start;
5426 : }
5427 :
5428 : /*
5429 : * There may be multiple netloc[:port] pairs, each separated from the next
5430 : * by a comma. When we initially enter this loop, "p" has been
5431 : * incremented past optional URI credential information at this point and
5432 : * now points at the "netloc" part of the URI. On subsequent loop
5433 : * iterations, "p" has been incremented past the comma separator and now
5434 : * points at the start of the next "netloc".
5435 : */
5436 : for (;;)
5437 : {
5438 : /*
5439 : * Look for IPv6 address.
5440 : */
5441 0 : if (*p == '[')
5442 : {
5443 0 : host = ++p;
5444 0 : while (*p && *p != ']')
5445 0 : ++p;
5446 0 : if (!*p)
5447 : {
5448 0 : printfPQExpBuffer(errorMessage,
5449 : libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
5450 : uri);
5451 0 : goto cleanup;
5452 : }
5453 0 : if (p == host)
5454 : {
5455 0 : printfPQExpBuffer(errorMessage,
5456 : libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
5457 : uri);
5458 0 : goto cleanup;
5459 : }
5460 :
5461 : /* Cut off the bracket and advance */
5462 0 : *(p++) = '\0';
5463 :
5464 : /*
5465 : * The address may be followed by a port specifier or a slash or a
5466 : * query or a separator comma.
5467 : */
5468 0 : if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5469 : {
5470 0 : printfPQExpBuffer(errorMessage,
5471 : libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
5472 0 : *p, (int) (p - buf + 1), uri);
5473 0 : goto cleanup;
5474 : }
5475 : }
5476 : else
5477 : {
5478 : /* not an IPv6 address: DNS-named or IPv4 netloc */
5479 0 : host = p;
5480 :
5481 : /*
5482 : * Look for port specifier (colon) or end of host specifier
5483 : * (slash) or query (question mark) or host separator (comma).
5484 : */
5485 0 : while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5486 0 : ++p;
5487 : }
5488 :
5489 : /* Save the hostname terminator before we null it */
5490 0 : prevchar = *p;
5491 0 : *p = '\0';
5492 :
5493 0 : appendPQExpBufferStr(&hostbuf, host);
5494 :
5495 0 : if (prevchar == ':')
5496 : {
5497 0 : const char *port = ++p; /* advance past host terminator */
5498 :
5499 0 : while (*p && *p != '/' && *p != '?' && *p != ',')
5500 0 : ++p;
5501 :
5502 0 : prevchar = *p;
5503 0 : *p = '\0';
5504 :
5505 0 : appendPQExpBufferStr(&portbuf, port);
5506 : }
5507 :
5508 0 : if (prevchar != ',')
5509 0 : break;
5510 0 : ++p; /* advance past comma separator */
5511 0 : appendPQExpBufferChar(&hostbuf, ',');
5512 0 : appendPQExpBufferChar(&portbuf, ',');
5513 0 : }
5514 :
5515 : /* Save final values for host and port. */
5516 0 : if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5517 : goto cleanup;
5518 0 : if (hostbuf.data[0] &&
5519 0 : !conninfo_storeval(options, "host", hostbuf.data,
5520 : errorMessage, false, true))
5521 0 : goto cleanup;
5522 0 : if (portbuf.data[0] &&
5523 0 : !conninfo_storeval(options, "port", portbuf.data,
5524 : errorMessage, false, true))
5525 0 : goto cleanup;
5526 :
5527 0 : if (prevchar && prevchar != '?')
5528 : {
5529 0 : const char *dbname = ++p; /* advance past host terminator */
5530 :
5531 : /* Look for query parameters */
5532 0 : while (*p && *p != '?')
5533 0 : ++p;
5534 :
5535 0 : prevchar = *p;
5536 0 : *p = '\0';
5537 :
5538 : /*
5539 : * Avoid setting dbname to an empty string, as it forces the default
5540 : * value (username) and ignores $PGDATABASE, as opposed to not setting
5541 : * it at all.
5542 : */
5543 0 : if (*dbname &&
5544 0 : !conninfo_storeval(options, "dbname", dbname,
5545 : errorMessage, false, true))
5546 0 : goto cleanup;
5547 : }
5548 :
5549 0 : if (prevchar)
5550 : {
5551 0 : ++p; /* advance past terminator */
5552 :
5553 0 : if (!conninfo_uri_parse_params(p, options, errorMessage))
5554 0 : goto cleanup;
5555 : }
5556 :
5557 : /* everything parsed okay */
5558 0 : retval = true;
5559 :
5560 : cleanup:
5561 0 : termPQExpBuffer(&hostbuf);
5562 0 : termPQExpBuffer(&portbuf);
5563 0 : if (buf)
5564 0 : free(buf);
5565 0 : return retval;
5566 : }
5567 :
5568 : /*
5569 : * Connection URI parameters parser routine
5570 : *
5571 : * If successful, returns true while connOptions is filled with parsed
5572 : * parameters. Otherwise, returns false and fills errorMessage appropriately.
5573 : *
5574 : * Destructively modifies 'params' buffer.
5575 : */
5576 : static bool
5577 0 : conninfo_uri_parse_params(char *params,
5578 : PQconninfoOption *connOptions,
5579 : PQExpBuffer errorMessage)
5580 : {
5581 0 : while (*params)
5582 : {
5583 0 : char *keyword = params;
5584 0 : char *value = NULL;
5585 0 : char *p = params;
5586 0 : bool malloced = false;
5587 :
5588 : /*
5589 : * Scan the params string for '=' and '&', marking the end of keyword
5590 : * and value respectively.
5591 : */
5592 : for (;;)
5593 : {
5594 0 : if (*p == '=')
5595 : {
5596 : /* Was there '=' already? */
5597 0 : if (value != NULL)
5598 : {
5599 0 : printfPQExpBuffer(errorMessage,
5600 : libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5601 : keyword);
5602 0 : return false;
5603 : }
5604 : /* Cut off keyword, advance to value */
5605 0 : *p++ = '\0';
5606 0 : value = p;
5607 : }
5608 0 : else if (*p == '&' || *p == '\0')
5609 : {
5610 : /*
5611 : * If not at the end, cut off value and advance; leave p
5612 : * pointing to start of the next parameter, if any.
5613 : */
5614 0 : if (*p != '\0')
5615 0 : *p++ = '\0';
5616 : /* Was there '=' at all? */
5617 0 : if (value == NULL)
5618 : {
5619 0 : printfPQExpBuffer(errorMessage,
5620 : libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5621 : keyword);
5622 0 : return false;
5623 : }
5624 : /* Got keyword and value, go process them. */
5625 0 : break;
5626 : }
5627 : else
5628 0 : ++p; /* Advance over all other bytes. */
5629 0 : }
5630 :
5631 0 : keyword = conninfo_uri_decode(keyword, errorMessage);
5632 0 : if (keyword == NULL)
5633 : {
5634 : /* conninfo_uri_decode already set an error message */
5635 0 : return false;
5636 : }
5637 0 : value = conninfo_uri_decode(value, errorMessage);
5638 0 : if (value == NULL)
5639 : {
5640 : /* conninfo_uri_decode already set an error message */
5641 0 : free(keyword);
5642 0 : return false;
5643 : }
5644 0 : malloced = true;
5645 :
5646 : /*
5647 : * Special keyword handling for improved JDBC compatibility.
5648 : */
5649 0 : if (strcmp(keyword, "ssl") == 0 &&
5650 0 : strcmp(value, "true") == 0)
5651 : {
5652 0 : free(keyword);
5653 0 : free(value);
5654 0 : malloced = false;
5655 :
5656 0 : keyword = "sslmode";
5657 0 : value = "require";
5658 : }
5659 :
5660 : /*
5661 : * Store the value if the corresponding option exists; ignore
5662 : * otherwise. At this point both keyword and value are not
5663 : * URI-encoded.
5664 : */
5665 0 : if (!conninfo_storeval(connOptions, keyword, value,
5666 : errorMessage, true, false))
5667 : {
5668 : /* Insert generic message if conninfo_storeval didn't give one. */
5669 0 : if (errorMessage->len == 0)
5670 0 : printfPQExpBuffer(errorMessage,
5671 : libpq_gettext("invalid URI query parameter: \"%s\"\n"),
5672 : keyword);
5673 : /* And fail. */
5674 0 : if (malloced)
5675 : {
5676 0 : free(keyword);
5677 0 : free(value);
5678 : }
5679 0 : return false;
5680 : }
5681 :
5682 0 : if (malloced)
5683 : {
5684 0 : free(keyword);
5685 0 : free(value);
5686 : }
5687 :
5688 : /* Proceed to next key=value pair, if any */
5689 0 : params = p;
5690 : }
5691 :
5692 0 : return true;
5693 : }
5694 :
5695 : /*
5696 : * Connection URI decoder routine
5697 : *
5698 : * If successful, returns the malloc'd decoded string.
5699 : * If not successful, returns NULL and fills errorMessage accordingly.
5700 : *
5701 : * The string is decoded by replacing any percent-encoded tokens with
5702 : * corresponding characters, while preserving any non-encoded characters. A
5703 : * percent-encoded token is a character triplet: a percent sign, followed by a
5704 : * pair of hexadecimal digits (0-9A-F), where lower- and upper-case letters are
5705 : * treated identically.
5706 : */
5707 : static char *
5708 0 : conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
5709 : {
5710 : char *buf;
5711 : char *p;
5712 0 : const char *q = str;
5713 :
5714 0 : buf = malloc(strlen(str) + 1);
5715 0 : if (buf == NULL)
5716 : {
5717 0 : printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5718 0 : return NULL;
5719 : }
5720 0 : p = buf;
5721 :
5722 : for (;;)
5723 : {
5724 0 : if (*q != '%')
5725 : {
5726 : /* copy and check for NUL terminator */
5727 0 : if (!(*(p++) = *(q++)))
5728 0 : break;
5729 : }
5730 : else
5731 : {
5732 : int hi;
5733 : int lo;
5734 : int c;
5735 :
5736 0 : ++q; /* skip the percent sign itself */
5737 :
5738 : /*
5739 : * Possible EOL will be caught by the first call to
5740 : * get_hexdigit(), so we never dereference an invalid q pointer.
5741 : */
5742 0 : if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
5743 : {
5744 0 : printfPQExpBuffer(errorMessage,
5745 : libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
5746 : str);
5747 0 : free(buf);
5748 0 : return NULL;
5749 : }
5750 :
5751 0 : c = (hi << 4) | lo;
5752 0 : if (c == 0)
5753 : {
5754 0 : printfPQExpBuffer(errorMessage,
5755 : libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
5756 : str);
5757 0 : free(buf);
5758 0 : return NULL;
5759 : }
5760 0 : *(p++) = c;
5761 : }
5762 0 : }
5763 :
5764 0 : return buf;
5765 : }
5766 :
5767 : /*
5768 : * Convert hexadecimal digit character to its integer value.
5769 : *
5770 : * If successful, returns true and value is filled with digit's base 16 value.
5771 : * If not successful, returns false.
5772 : *
5773 : * Lower- and upper-case letters in the range A-F are treated identically.
5774 : */
5775 : static bool
5776 0 : get_hexdigit(char digit, int *value)
5777 : {
5778 0 : if ('0' <= digit && digit <= '9')
5779 0 : *value = digit - '0';
5780 0 : else if ('A' <= digit && digit <= 'F')
5781 0 : *value = digit - 'A' + 10;
5782 0 : else if ('a' <= digit && digit <= 'f')
5783 0 : *value = digit - 'a' + 10;
5784 : else
5785 0 : return false;
5786 :
5787 0 : return true;
5788 : }
5789 :
5790 : /*
5791 : * Find an option value corresponding to the keyword in the connOptions array.
5792 : *
5793 : * If successful, returns a pointer to the corresponding option's value.
5794 : * If not successful, returns NULL.
5795 : */
5796 : static const char *
5797 5859 : conninfo_getval(PQconninfoOption *connOptions,
5798 : const char *keyword)
5799 : {
5800 : PQconninfoOption *option;
5801 :
5802 5859 : option = conninfo_find(connOptions, keyword);
5803 :
5804 5859 : return option ? option->val : NULL;
5805 : }
5806 :
5807 : /*
5808 : * Store a (new) value for an option corresponding to the keyword in
5809 : * connOptions array.
5810 : *
5811 : * If uri_decode is true, the value is URI-decoded. The keyword is always
5812 : * assumed to be non URI-encoded.
5813 : *
5814 : * If successful, returns a pointer to the corresponding PQconninfoOption,
5815 : * which value is replaced with a strdup'd copy of the passed value string.
5816 : * The existing value for the option is free'd before replacing, if any.
5817 : *
5818 : * If not successful, returns NULL and fills errorMessage accordingly.
5819 : * However, if the reason of failure is an invalid keyword being passed and
5820 : * ignoreMissing is TRUE, errorMessage will be left untouched.
5821 : */
5822 : static PQconninfoOption *
5823 37 : conninfo_storeval(PQconninfoOption *connOptions,
5824 : const char *keyword, const char *value,
5825 : PQExpBuffer errorMessage, bool ignoreMissing,
5826 : bool uri_decode)
5827 : {
5828 : PQconninfoOption *option;
5829 : char *value_copy;
5830 :
5831 : /*
5832 : * For backwards compatibility, requiressl=1 gets translated to
5833 : * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
5834 : * (which is the default for sslmode).
5835 : */
5836 37 : if (strcmp(keyword, "requiressl") == 0)
5837 : {
5838 0 : keyword = "sslmode";
5839 0 : if (value[0] == '1')
5840 0 : value = "require";
5841 : else
5842 0 : value = "prefer";
5843 : }
5844 :
5845 37 : option = conninfo_find(connOptions, keyword);
5846 37 : if (option == NULL)
5847 : {
5848 0 : if (!ignoreMissing)
5849 0 : printfPQExpBuffer(errorMessage,
5850 : libpq_gettext("invalid connection option \"%s\"\n"),
5851 : keyword);
5852 0 : return NULL;
5853 : }
5854 :
5855 37 : if (uri_decode)
5856 : {
5857 0 : value_copy = conninfo_uri_decode(value, errorMessage);
5858 0 : if (value_copy == NULL)
5859 : /* conninfo_uri_decode already set an error message */
5860 0 : return NULL;
5861 : }
5862 : else
5863 : {
5864 37 : value_copy = strdup(value);
5865 37 : if (value_copy == NULL)
5866 : {
5867 0 : printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5868 0 : return NULL;
5869 : }
5870 : }
5871 :
5872 37 : if (option->val)
5873 0 : free(option->val);
5874 37 : option->val = value_copy;
5875 :
5876 37 : return option;
5877 : }
5878 :
5879 : /*
5880 : * Find a PQconninfoOption option corresponding to the keyword in the
5881 : * connOptions array.
5882 : *
5883 : * If successful, returns a pointer to the corresponding PQconninfoOption
5884 : * structure.
5885 : * If not successful, returns NULL.
5886 : */
5887 : static PQconninfoOption *
5888 5896 : conninfo_find(PQconninfoOption *connOptions, const char *keyword)
5889 : {
5890 : PQconninfoOption *option;
5891 :
5892 88144 : for (option = connOptions; option->keyword != NULL; option++)
5893 : {
5894 88144 : if (strcmp(option->keyword, keyword) == 0)
5895 5896 : return option;
5896 : }
5897 :
5898 0 : return NULL;
5899 : }
5900 :
5901 :
5902 : /*
5903 : * Return the connection options used for the connection
5904 : */
5905 : PQconninfoOption *
5906 0 : PQconninfo(PGconn *conn)
5907 : {
5908 : PQExpBufferData errorBuf;
5909 : PQconninfoOption *connOptions;
5910 :
5911 0 : if (conn == NULL)
5912 0 : return NULL;
5913 :
5914 : /* We don't actually report any errors here, but callees want a buffer */
5915 0 : initPQExpBuffer(&errorBuf);
5916 0 : if (PQExpBufferDataBroken(errorBuf))
5917 0 : return NULL; /* out of memory already :-( */
5918 :
5919 0 : connOptions = conninfo_init(&errorBuf);
5920 :
5921 0 : if (connOptions != NULL)
5922 : {
5923 : const internalPQconninfoOption *option;
5924 :
5925 0 : for (option = PQconninfoOptions; option->keyword; option++)
5926 : {
5927 : char **connmember;
5928 :
5929 0 : if (option->connofs < 0)
5930 0 : continue;
5931 :
5932 0 : connmember = (char **) ((char *) conn + option->connofs);
5933 :
5934 0 : if (*connmember)
5935 0 : conninfo_storeval(connOptions, option->keyword, *connmember,
5936 : &errorBuf, true, false);
5937 : }
5938 : }
5939 :
5940 0 : termPQExpBuffer(&errorBuf);
5941 :
5942 0 : return connOptions;
5943 : }
5944 :
5945 :
5946 : void
5947 474 : PQconninfoFree(PQconninfoOption *connOptions)
5948 : {
5949 : PQconninfoOption *option;
5950 :
5951 474 : if (connOptions == NULL)
5952 691 : return;
5953 :
5954 7453 : for (option = connOptions; option->keyword != NULL; option++)
5955 : {
5956 7196 : if (option->val != NULL)
5957 2643 : free(option->val);
5958 : }
5959 257 : free(connOptions);
5960 : }
5961 :
5962 :
5963 : /* =========== accessor functions for PGconn ========= */
5964 : char *
5965 248 : PQdb(const PGconn *conn)
5966 : {
5967 248 : if (!conn)
5968 0 : return NULL;
5969 248 : return conn->dbName;
5970 : }
5971 :
5972 : char *
5973 314 : PQuser(const PGconn *conn)
5974 : {
5975 314 : if (!conn)
5976 0 : return NULL;
5977 314 : return conn->pguser;
5978 : }
5979 :
5980 : char *
5981 35 : PQpass(const PGconn *conn)
5982 : {
5983 35 : char *password = NULL;
5984 :
5985 35 : if (!conn)
5986 0 : return NULL;
5987 35 : if (conn->connhost != NULL)
5988 35 : password = conn->connhost[conn->whichhost].password;
5989 35 : if (password == NULL)
5990 35 : password = conn->pgpass;
5991 : /* Historically we've returned "" not NULL for no password specified */
5992 35 : if (password == NULL)
5993 35 : password = "";
5994 35 : return password;
5995 : }
5996 :
5997 : char *
5998 314 : PQhost(const PGconn *conn)
5999 : {
6000 314 : if (!conn)
6001 0 : return NULL;
6002 628 : if (conn->connhost != NULL &&
6003 314 : conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS)
6004 314 : return conn->connhost[conn->whichhost].host;
6005 0 : else if (conn->pghost != NULL && conn->pghost[0] != '\0')
6006 0 : return conn->pghost;
6007 : else
6008 : {
6009 : #ifdef HAVE_UNIX_SOCKETS
6010 0 : return DEFAULT_PGSOCKET_DIR;
6011 : #else
6012 : return DefaultHost;
6013 : #endif
6014 : }
6015 : }
6016 :
6017 : char *
6018 314 : PQport(const PGconn *conn)
6019 : {
6020 314 : if (!conn)
6021 0 : return NULL;
6022 314 : if (conn->connhost != NULL)
6023 314 : return conn->connhost[conn->whichhost].port;
6024 0 : return conn->pgport;
6025 : }
6026 :
6027 : char *
6028 0 : PQtty(const PGconn *conn)
6029 : {
6030 0 : if (!conn)
6031 0 : return NULL;
6032 0 : return conn->pgtty;
6033 : }
6034 :
6035 : char *
6036 0 : PQoptions(const PGconn *conn)
6037 : {
6038 0 : if (!conn)
6039 0 : return NULL;
6040 0 : return conn->pgoptions;
6041 : }
6042 :
6043 : ConnStatusType
6044 3608 : PQstatus(const PGconn *conn)
6045 : {
6046 3608 : if (!conn)
6047 0 : return CONNECTION_BAD;
6048 3608 : return conn->status;
6049 : }
6050 :
6051 : PGTransactionStatusType
6052 24284 : PQtransactionStatus(const PGconn *conn)
6053 : {
6054 24284 : if (!conn || conn->status != CONNECTION_OK)
6055 0 : return PQTRANS_UNKNOWN;
6056 24284 : if (conn->asyncStatus != PGASYNC_IDLE)
6057 1 : return PQTRANS_ACTIVE;
6058 24283 : return conn->xactStatus;
6059 : }
6060 :
6061 : const char *
6062 47086 : PQparameterStatus(const PGconn *conn, const char *paramName)
6063 : {
6064 : const pgParameterStatus *pstatus;
6065 :
6066 47086 : if (!conn || !paramName)
6067 0 : return NULL;
6068 105698 : for (pstatus = conn->pstatus; pstatus != NULL; pstatus = pstatus->next)
6069 : {
6070 105698 : if (strcmp(pstatus->name, paramName) == 0)
6071 47086 : return pstatus->value;
6072 : }
6073 0 : return NULL;
6074 : }
6075 :
6076 : int
6077 0 : PQprotocolVersion(const PGconn *conn)
6078 : {
6079 0 : if (!conn)
6080 0 : return 0;
6081 0 : if (conn->status == CONNECTION_BAD)
6082 0 : return 0;
6083 0 : return PG_PROTOCOL_MAJOR(conn->pversion);
6084 : }
6085 :
6086 : int
6087 215 : PQserverVersion(const PGconn *conn)
6088 : {
6089 215 : if (!conn)
6090 0 : return 0;
6091 215 : if (conn->status == CONNECTION_BAD)
6092 0 : return 0;
6093 215 : return conn->sversion;
6094 : }
6095 :
6096 : char *
6097 3222 : PQerrorMessage(const PGconn *conn)
6098 : {
6099 3222 : if (!conn)
6100 0 : return libpq_gettext("connection pointer is NULL\n");
6101 :
6102 3222 : return conn->errorMessage.data;
6103 : }
6104 :
6105 : /*
6106 : * In Windows, socket values are unsigned, and an invalid socket value
6107 : * (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
6108 : * warning). Ideally we would return an unsigned value for PQsocket() on
6109 : * Windows, but that would cause the function's return value to differ from
6110 : * Unix, so we just return -1 for invalid sockets.
6111 : * http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
6112 : * http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
6113 : */
6114 : int
6115 0 : PQsocket(const PGconn *conn)
6116 : {
6117 0 : if (!conn)
6118 0 : return -1;
6119 0 : return (conn->sock != PGINVALID_SOCKET) ? conn->sock : -1;
6120 : }
6121 :
6122 : int
6123 0 : PQbackendPID(const PGconn *conn)
6124 : {
6125 0 : if (!conn || conn->status != CONNECTION_OK)
6126 0 : return 0;
6127 0 : return conn->be_pid;
6128 : }
6129 :
6130 : int
6131 2 : PQconnectionNeedsPassword(const PGconn *conn)
6132 : {
6133 : char *password;
6134 :
6135 2 : if (!conn)
6136 0 : return false;
6137 2 : password = PQpass(conn);
6138 2 : if (conn->password_needed &&
6139 0 : (password == NULL || password[0] == '\0'))
6140 0 : return true;
6141 : else
6142 2 : return false;
6143 : }
6144 :
6145 : int
6146 0 : PQconnectionUsedPassword(const PGconn *conn)
6147 : {
6148 0 : if (!conn)
6149 0 : return false;
6150 0 : if (conn->password_needed)
6151 0 : return true;
6152 : else
6153 0 : return false;
6154 : }
6155 :
6156 : int
6157 24785 : PQclientEncoding(const PGconn *conn)
6158 : {
6159 24785 : if (!conn || conn->status != CONNECTION_OK)
6160 0 : return -1;
6161 24785 : return conn->client_encoding;
6162 : }
6163 :
6164 : int
6165 0 : PQsetClientEncoding(PGconn *conn, const char *encoding)
6166 : {
6167 : char qbuf[128];
6168 : static const char query[] = "set client_encoding to '%s'";
6169 : PGresult *res;
6170 : int status;
6171 :
6172 0 : if (!conn || conn->status != CONNECTION_OK)
6173 0 : return -1;
6174 :
6175 0 : if (!encoding)
6176 0 : return -1;
6177 :
6178 : /* Resolve special "auto" value from the locale */
6179 0 : if (strcmp(encoding, "auto") == 0)
6180 0 : encoding = pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true));
6181 :
6182 : /* check query buffer overflow */
6183 0 : if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
6184 0 : return -1;
6185 :
6186 : /* ok, now send a query */
6187 0 : sprintf(qbuf, query, encoding);
6188 0 : res = PQexec(conn, qbuf);
6189 :
6190 0 : if (res == NULL)
6191 0 : return -1;
6192 0 : if (res->resultStatus != PGRES_COMMAND_OK)
6193 0 : status = -1;
6194 : else
6195 : {
6196 : /*
6197 : * In protocol 2 we have to assume the setting will stick, and adjust
6198 : * our state immediately. In protocol 3 and up we can rely on the
6199 : * backend to report the parameter value, and we'll change state at
6200 : * that time.
6201 : */
6202 0 : if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
6203 0 : pqSaveParameterStatus(conn, "client_encoding", encoding);
6204 0 : status = 0; /* everything is ok */
6205 : }
6206 0 : PQclear(res);
6207 0 : return status;
6208 : }
6209 :
6210 : PGVerbosity
6211 249 : PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
6212 : {
6213 : PGVerbosity old;
6214 :
6215 249 : if (!conn)
6216 0 : return PQERRORS_DEFAULT;
6217 249 : old = conn->verbosity;
6218 249 : conn->verbosity = verbosity;
6219 249 : return old;
6220 : }
6221 :
6222 : PGContextVisibility
6223 218 : PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
6224 : {
6225 : PGContextVisibility old;
6226 :
6227 218 : if (!conn)
6228 0 : return PQSHOW_CONTEXT_ERRORS;
6229 218 : old = conn->show_context;
6230 218 : conn->show_context = show_context;
6231 218 : return old;
6232 : }
6233 :
6234 : void
6235 0 : PQtrace(PGconn *conn, FILE *debug_port)
6236 : {
6237 0 : if (conn == NULL)
6238 0 : return;
6239 0 : PQuntrace(conn);
6240 0 : conn->Pfdebug = debug_port;
6241 : }
6242 :
6243 : void
6244 0 : PQuntrace(PGconn *conn)
6245 : {
6246 0 : if (conn == NULL)
6247 0 : return;
6248 0 : if (conn->Pfdebug)
6249 : {
6250 0 : fflush(conn->Pfdebug);
6251 0 : conn->Pfdebug = NULL;
6252 : }
6253 : }
6254 :
6255 : PQnoticeReceiver
6256 0 : PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
6257 : {
6258 : PQnoticeReceiver old;
6259 :
6260 0 : if (conn == NULL)
6261 0 : return NULL;
6262 :
6263 0 : old = conn->noticeHooks.noticeRec;
6264 0 : if (proc)
6265 : {
6266 0 : conn->noticeHooks.noticeRec = proc;
6267 0 : conn->noticeHooks.noticeRecArg = arg;
6268 : }
6269 0 : return old;
6270 : }
6271 :
6272 : PQnoticeProcessor
6273 215 : PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
6274 : {
6275 : PQnoticeProcessor old;
6276 :
6277 215 : if (conn == NULL)
6278 0 : return NULL;
6279 :
6280 215 : old = conn->noticeHooks.noticeProc;
6281 215 : if (proc)
6282 : {
6283 215 : conn->noticeHooks.noticeProc = proc;
6284 215 : conn->noticeHooks.noticeProcArg = arg;
6285 : }
6286 215 : return old;
6287 : }
6288 :
6289 : /*
6290 : * The default notice message receiver just gets the standard notice text
6291 : * and sends it to the notice processor. This two-level setup exists
6292 : * mostly for backwards compatibility; perhaps we should deprecate use of
6293 : * PQsetNoticeProcessor?
6294 : */
6295 : static void
6296 1739 : defaultNoticeReceiver(void *arg, const PGresult *res)
6297 : {
6298 : (void) arg; /* not used */
6299 1739 : if (res->noticeHooks.noticeProc != NULL)
6300 3478 : (*res->noticeHooks.noticeProc) (res->noticeHooks.noticeProcArg,
6301 1739 : PQresultErrorMessage(res));
6302 1739 : }
6303 :
6304 : /*
6305 : * The default notice message processor just prints the
6306 : * message on stderr. Applications can override this if they
6307 : * want the messages to go elsewhere (a window, for example).
6308 : * Note that simply discarding notices is probably a bad idea.
6309 : */
6310 : static void
6311 0 : defaultNoticeProcessor(void *arg, const char *message)
6312 : {
6313 : (void) arg; /* not used */
6314 : /* Note: we expect the supplied string to end with a newline already. */
6315 0 : fprintf(stderr, "%s", message);
6316 0 : }
6317 :
6318 : /*
6319 : * returns a pointer to the next token or NULL if the current
6320 : * token doesn't match
6321 : */
6322 : static char *
6323 0 : pwdfMatchesString(char *buf, char *token)
6324 : {
6325 : char *tbuf,
6326 : *ttok;
6327 0 : bool bslash = false;
6328 :
6329 0 : if (buf == NULL || token == NULL)
6330 0 : return NULL;
6331 0 : tbuf = buf;
6332 0 : ttok = token;
6333 0 : if (tbuf[0] == '*' && tbuf[1] == ':')
6334 0 : return tbuf + 2;
6335 0 : while (*tbuf != 0)
6336 : {
6337 0 : if (*tbuf == '\\' && !bslash)
6338 : {
6339 0 : tbuf++;
6340 0 : bslash = true;
6341 : }
6342 0 : if (*tbuf == ':' && *ttok == 0 && !bslash)
6343 0 : return tbuf + 1;
6344 0 : bslash = false;
6345 0 : if (*ttok == 0)
6346 0 : return NULL;
6347 0 : if (*tbuf == *ttok)
6348 : {
6349 0 : tbuf++;
6350 0 : ttok++;
6351 : }
6352 : else
6353 0 : return NULL;
6354 : }
6355 0 : return NULL;
6356 : }
6357 :
6358 : /* Get a password from the password file. Return value is malloc'd. */
6359 : static char *
6360 217 : passwordFromFile(char *hostname, char *port, char *dbname,
6361 : char *username, char *pgpassfile)
6362 : {
6363 : FILE *fp;
6364 : struct stat stat_buf;
6365 :
6366 : #define LINELEN NAMEDATALEN*5
6367 : char buf[LINELEN];
6368 :
6369 217 : if (dbname == NULL || strlen(dbname) == 0)
6370 0 : return NULL;
6371 :
6372 217 : if (username == NULL || strlen(username) == 0)
6373 0 : return NULL;
6374 :
6375 : /* 'localhost' matches pghost of '' or the default socket directory */
6376 217 : if (hostname == NULL)
6377 0 : hostname = DefaultHost;
6378 217 : else if (is_absolute_path(hostname))
6379 :
6380 : /*
6381 : * We should probably use canonicalize_path(), but then we have to
6382 : * bring path.c into libpq, and it doesn't seem worth it.
6383 : */
6384 217 : if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
6385 0 : hostname = DefaultHost;
6386 :
6387 217 : if (port == NULL)
6388 0 : port = DEF_PGPORT_STR;
6389 :
6390 : /* If password file cannot be opened, ignore it. */
6391 217 : if (stat(pgpassfile, &stat_buf) != 0)
6392 217 : return NULL;
6393 :
6394 : #ifndef WIN32
6395 0 : if (!S_ISREG(stat_buf.st_mode))
6396 : {
6397 0 : fprintf(stderr,
6398 : libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
6399 : pgpassfile);
6400 0 : return NULL;
6401 : }
6402 :
6403 : /* If password file is insecure, alert the user and ignore it. */
6404 0 : if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
6405 : {
6406 0 : fprintf(stderr,
6407 : libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
6408 : pgpassfile);
6409 0 : return NULL;
6410 : }
6411 : #else
6412 :
6413 : /*
6414 : * On Win32, the directory is protected, so we don't have to check the
6415 : * file.
6416 : */
6417 : #endif
6418 :
6419 0 : fp = fopen(pgpassfile, "r");
6420 0 : if (fp == NULL)
6421 0 : return NULL;
6422 :
6423 0 : while (!feof(fp) && !ferror(fp))
6424 : {
6425 0 : char *t = buf,
6426 : *ret,
6427 : *p1,
6428 : *p2;
6429 : int len;
6430 :
6431 0 : if (fgets(buf, sizeof(buf), fp) == NULL)
6432 0 : break;
6433 :
6434 0 : len = strlen(buf);
6435 :
6436 : /* Remove trailing newline */
6437 0 : if (len > 0 && buf[len - 1] == '\n')
6438 : {
6439 0 : buf[--len] = '\0';
6440 : /* Handle DOS-style line endings, too, even when not on Windows */
6441 0 : if (len > 0 && buf[len - 1] == '\r')
6442 0 : buf[--len] = '\0';
6443 : }
6444 :
6445 0 : if (len == 0)
6446 0 : continue;
6447 :
6448 0 : if ((t = pwdfMatchesString(t, hostname)) == NULL ||
6449 0 : (t = pwdfMatchesString(t, port)) == NULL ||
6450 0 : (t = pwdfMatchesString(t, dbname)) == NULL ||
6451 : (t = pwdfMatchesString(t, username)) == NULL)
6452 0 : continue;
6453 :
6454 : /* Found a match. */
6455 0 : ret = strdup(t);
6456 0 : fclose(fp);
6457 :
6458 0 : if (!ret)
6459 : {
6460 : /* Out of memory. XXX: an error message would be nice. */
6461 0 : return NULL;
6462 : }
6463 :
6464 : /* De-escape password. */
6465 0 : for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
6466 : {
6467 0 : if (*p1 == '\\' && p1[1] != '\0')
6468 0 : ++p1;
6469 0 : *p2 = *p1;
6470 : }
6471 0 : *p2 = '\0';
6472 :
6473 0 : return ret;
6474 : }
6475 :
6476 0 : fclose(fp);
6477 0 : return NULL;
6478 :
6479 : #undef LINELEN
6480 : }
6481 :
6482 :
6483 : /*
6484 : * If the connection failed due to bad password, we should mention
6485 : * if we got the password from the pgpassfile.
6486 : */
6487 : static void
6488 2 : pgpassfileWarning(PGconn *conn)
6489 : {
6490 : /* If it was 'invalid authorization', add pgpassfile mention */
6491 : /* only works with >= 9.0 servers */
6492 2 : if (conn->pgpassfile_used && conn->password_needed && conn->result)
6493 : {
6494 0 : const char *sqlstate = PQresultErrorField(conn->result,
6495 : PG_DIAG_SQLSTATE);
6496 :
6497 0 : if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6498 0 : appendPQExpBuffer(&conn->errorMessage,
6499 : libpq_gettext("password retrieved from file \"%s\"\n"),
6500 : conn->pgpassfile);
6501 : }
6502 2 : }
6503 :
6504 :
6505 : /*
6506 : * Obtain user's home directory, return in given buffer
6507 : *
6508 : * On Unix, this actually returns the user's home directory. On Windows
6509 : * it returns the PostgreSQL-specific application data folder.
6510 : *
6511 : * This is essentially the same as get_home_path(), but we don't use that
6512 : * because we don't want to pull path.c into libpq (it pollutes application
6513 : * namespace)
6514 : */
6515 : bool
6516 217 : pqGetHomeDirectory(char *buf, int bufsize)
6517 : {
6518 : #ifndef WIN32
6519 : char pwdbuf[BUFSIZ];
6520 : struct passwd pwdstr;
6521 217 : struct passwd *pwd = NULL;
6522 :
6523 217 : (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
6524 217 : if (pwd == NULL)
6525 0 : return false;
6526 217 : strlcpy(buf, pwd->pw_dir, bufsize);
6527 217 : return true;
6528 : #else
6529 : char tmppath[MAX_PATH];
6530 :
6531 : ZeroMemory(tmppath, sizeof(tmppath));
6532 : if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
6533 : return false;
6534 : snprintf(buf, bufsize, "%s/postgresql", tmppath);
6535 : return true;
6536 : #endif
6537 : }
6538 :
6539 : /*
6540 : * To keep the API consistent, the locking stubs are always provided, even
6541 : * if they are not required.
6542 : */
6543 :
6544 : static void
6545 368 : default_threadlock(int acquire)
6546 : {
6547 : #ifdef ENABLE_THREAD_SAFETY
6548 : #ifndef WIN32
6549 : static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6550 : #else
6551 : static pthread_mutex_t singlethread_lock = NULL;
6552 : static long mutex_initlock = 0;
6553 :
6554 : if (singlethread_lock == NULL)
6555 : {
6556 : while (InterlockedExchange(&mutex_initlock, 1) == 1)
6557 : /* loop, another thread own the lock */ ;
6558 : if (singlethread_lock == NULL)
6559 : {
6560 : if (pthread_mutex_init(&singlethread_lock, NULL))
6561 : PGTHREAD_ERROR("failed to initialize mutex");
6562 : }
6563 : InterlockedExchange(&mutex_initlock, 0);
6564 : }
6565 : #endif
6566 368 : if (acquire)
6567 : {
6568 184 : if (pthread_mutex_lock(&singlethread_lock))
6569 0 : PGTHREAD_ERROR("failed to lock mutex");
6570 : }
6571 : else
6572 : {
6573 184 : if (pthread_mutex_unlock(&singlethread_lock))
6574 0 : PGTHREAD_ERROR("failed to unlock mutex");
6575 : }
6576 : #endif
6577 368 : }
6578 :
6579 : pgthreadlock_t
6580 0 : PQregisterThreadLock(pgthreadlock_t newhandler)
6581 : {
6582 0 : pgthreadlock_t prev = pg_g_threadlock;
6583 :
6584 0 : if (newhandler)
6585 0 : pg_g_threadlock = newhandler;
6586 : else
6587 0 : pg_g_threadlock = default_threadlock;
6588 :
6589 0 : return prev;
6590 : }
|