34#include "pg_config_paths.h"
42#define _WIN32_IE 0x0500
68#define LDAP_DEPRECATED 1
70typedef struct timeval LDAP_TIMEVAL;
77#define PGPASSFILE ".pgpass"
79#define PGPASSFILE "pgpass.conf"
88#define ERRCODE_APPNAME_UNKNOWN "42704"
91#define ERRCODE_INVALID_PASSWORD "28P01"
93#define ERRCODE_CANNOT_CONNECT_NOW "57P03"
99#if defined(TCP_KEEPIDLE)
101#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
102#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
103#elif defined(TCP_KEEPALIVE_THRESHOLD)
105#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
106#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
107#elif defined(TCP_KEEPALIVE) && defined(__darwin__)
110#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
111#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
118#define DefaultHost "localhost"
119#define DefaultOption ""
121#define DefaultChannelBinding "prefer"
123#define DefaultChannelBinding "disable"
125#define DefaultTargetSessionAttrs "any"
126#define DefaultLoadBalanceHosts "disable"
128#define DefaultSSLMode "prefer"
129#define DefaultSSLCertMode "allow"
131#define DefaultSSLMode "disable"
132#define DefaultSSLCertMode "disable"
134#define DefaultSSLNegotiation "postgres"
137#define DefaultGSSMode "prefer"
139#define DefaultGSSMode "disable"
193 {
"service",
"PGSERVICE", NULL, NULL,
194 "Database-Service",
"", 20,
195 offsetof(
struct pg_conn, pgservice)},
197 {
"user",
"PGUSER", NULL, NULL,
198 "Database-User",
"", 20,
199 offsetof(
struct pg_conn, pguser)},
201 {
"password",
"PGPASSWORD", NULL, NULL,
202 "Database-Password",
"*", 20,
203 offsetof(
struct pg_conn, pgpass)},
205 {
"passfile",
"PGPASSFILE", NULL, NULL,
206 "Database-Password-File",
"", 64,
207 offsetof(
struct pg_conn, pgpassfile)},
210 "Channel-Binding",
"", 8,
211 offsetof(
struct pg_conn, channel_binding)},
213 {
"connect_timeout",
"PGCONNECT_TIMEOUT", NULL, NULL,
214 "Connect-timeout",
"", 10,
215 offsetof(
struct pg_conn, connect_timeout)},
217 {
"dbname",
"PGDATABASE", NULL, NULL,
218 "Database-Name",
"", 20,
221 {
"host",
"PGHOST", NULL, NULL,
222 "Database-Host",
"", 40,
225 {
"hostaddr",
"PGHOSTADDR", NULL, NULL,
226 "Database-Host-IP-Address",
"", 45,
227 offsetof(
struct pg_conn, pghostaddr)},
229 {
"port",
"PGPORT", DEF_PGPORT_STR, NULL,
230 "Database-Port",
"", 6,
233 {
"client_encoding",
"PGCLIENTENCODING", NULL, NULL,
234 "Client-Encoding",
"", 10,
235 offsetof(
struct pg_conn, client_encoding_initial)},
238 "Backend-Options",
"", 40,
239 offsetof(
struct pg_conn, pgoptions)},
241 {
"application_name",
"PGAPPNAME", NULL, NULL,
242 "Application-Name",
"", 64,
243 offsetof(
struct pg_conn, appname)},
245 {
"fallback_application_name", NULL, NULL, NULL,
246 "Fallback-Application-Name",
"", 64,
247 offsetof(
struct pg_conn, fbappname)},
249 {
"keepalives", NULL, NULL, NULL,
250 "TCP-Keepalives",
"", 1,
251 offsetof(
struct pg_conn, keepalives)},
253 {
"keepalives_idle", NULL, NULL, NULL,
254 "TCP-Keepalives-Idle",
"", 10,
255 offsetof(
struct pg_conn, keepalives_idle)},
257 {
"keepalives_interval", NULL, NULL, NULL,
258 "TCP-Keepalives-Interval",
"", 10,
259 offsetof(
struct pg_conn, keepalives_interval)},
261 {
"keepalives_count", NULL, NULL, NULL,
262 "TCP-Keepalives-Count",
"", 10,
263 offsetof(
struct pg_conn, keepalives_count)},
265 {
"tcp_user_timeout", NULL, NULL, NULL,
266 "TCP-User-Timeout",
"", 10,
267 offsetof(
struct pg_conn, pgtcp_user_timeout)},
277 offsetof(
struct pg_conn, sslmode)},
280 "SSL-Negotiation",
"", 9,
281 offsetof(
struct pg_conn, sslnegotiation)},
283 {
"sslcompression",
"PGSSLCOMPRESSION",
"0", NULL,
284 "SSL-Compression",
"", 1,
285 offsetof(
struct pg_conn, sslcompression)},
287 {
"sslcert",
"PGSSLCERT", NULL, NULL,
288 "SSL-Client-Cert",
"", 64,
289 offsetof(
struct pg_conn, sslcert)},
291 {
"sslkey",
"PGSSLKEY", NULL, NULL,
292 "SSL-Client-Key",
"", 64,
293 offsetof(
struct pg_conn, sslkey)},
295 {
"sslcertmode",
"PGSSLCERTMODE", NULL, NULL,
296 "SSL-Client-Cert-Mode",
"", 8,
297 offsetof(
struct pg_conn, sslcertmode)},
299 {
"sslpassword", NULL, NULL, NULL,
300 "SSL-Client-Key-Password",
"*", 20,
301 offsetof(
struct pg_conn, sslpassword)},
303 {
"sslrootcert",
"PGSSLROOTCERT", NULL, NULL,
304 "SSL-Root-Certificate",
"", 64,
305 offsetof(
struct pg_conn, sslrootcert)},
307 {
"sslcrl",
"PGSSLCRL", NULL, NULL,
308 "SSL-Revocation-List",
"", 64,
309 offsetof(
struct pg_conn, sslcrl)},
311 {
"sslcrldir",
"PGSSLCRLDIR", NULL, NULL,
312 "SSL-Revocation-List-Dir",
"", 64,
313 offsetof(
struct pg_conn, sslcrldir)},
315 {
"sslsni",
"PGSSLSNI",
"1", NULL,
317 offsetof(
struct pg_conn, sslsni)},
319 {
"requirepeer",
"PGREQUIREPEER", NULL, NULL,
320 "Require-Peer",
"", 10,
321 offsetof(
struct pg_conn, requirepeer)},
323 {
"require_auth",
"PGREQUIREAUTH", NULL, NULL,
324 "Require-Auth",
"", 14,
325 offsetof(
struct pg_conn, require_auth)},
327 {
"ssl_min_protocol_version",
"PGSSLMINPROTOCOLVERSION",
"TLSv1.2", NULL,
328 "SSL-Minimum-Protocol-Version",
"", 8,
331 {
"ssl_max_protocol_version",
"PGSSLMAXPROTOCOLVERSION", NULL, NULL,
332 "SSL-Maximum-Protocol-Version",
"", 8,
340 "GSSENC-Mode",
"", 8,
341 offsetof(
struct pg_conn, gssencmode)},
344 {
"krbsrvname",
"PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
345 "Kerberos-service-name",
"", 20,
346 offsetof(
struct pg_conn, krbsrvname)},
348 {
"gsslib",
"PGGSSLIB", NULL, NULL,
349 "GSS-library",
"", 7,
350 offsetof(
struct pg_conn, gsslib)},
352 {
"gssdelegation",
"PGGSSDELEGATION",
"0", NULL,
353 "GSS-delegation",
"", 1,
354 offsetof(
struct pg_conn, gssdelegation)},
356 {
"replication", NULL, NULL, NULL,
357 "Replication",
"D", 5,
358 offsetof(
struct pg_conn, replication)},
360 {
"target_session_attrs",
"PGTARGETSESSIONATTRS",
362 "Target-Session-Attrs",
"", 15,
363 offsetof(
struct pg_conn, target_session_attrs)},
365 {
"load_balance_hosts",
"PGLOADBALANCEHOSTS",
367 "Load-Balance-Hosts",
"", 8,
368 offsetof(
struct pg_conn, load_balance_hosts)},
370 {
"scram_client_key", NULL, NULL, NULL,
"SCRAM-Client-Key",
"D",
SCRAM_MAX_KEY_LEN * 2,
371 offsetof(
struct pg_conn, scram_client_key)},
373 {
"scram_server_key", NULL, NULL, NULL,
"SCRAM-Server-Key",
"D",
SCRAM_MAX_KEY_LEN * 2,
374 offsetof(
struct pg_conn, scram_server_key)},
377 {NULL, NULL, NULL, NULL,
385 "PGDATESTYLE",
"datestyle"
403#define SASL_MECHANISM_COUNT lengthof(supported_sasl_mechs)
411#if defined(USE_SSL) || defined(ENABLE_GSS)
412static int encryption_negotiation_failed(
PGconn *
conn);
432 bool use_defaults,
int expand_dbname);
445 const char *keyword);
447 const char *keyword,
const char *
value,
448 PQExpBuffer errorMessage,
bool ignoreMissing,
bool uri_decode);
450 const char *keyword);
462 const char *
username,
const char *pgpassfile);
527 if (
conn->gcred != GSS_C_NO_CREDENTIAL)
529 gss_release_cred(&min_s, &
conn->gcred);
530 conn->gcred = GSS_C_NO_CREDENTIAL;
533 gss_delete_sec_context(&min_s, &
conn->gctx, GSS_C_NO_BUFFER);
535 gss_release_name(&min_s, &
conn->gtarg_nam);
536 if (
conn->gss_SendBuffer)
539 conn->gss_SendBuffer = NULL;
541 if (
conn->gss_RecvBuffer)
544 conn->gss_RecvBuffer = NULL;
546 if (
conn->gss_ResultBuffer)
549 conn->gss_ResultBuffer = NULL;
551 conn->gssenc =
false;
555 if (
conn->sspitarget)
558 conn->sspitarget = NULL;
562 FreeCredentialsHandle(
conn->sspicred);
564 conn->sspicred = NULL;
568 DeleteSecurityContext(
conn->sspictx);
570 conn->sspictx = NULL;
588 while (queue != NULL)
619 while (notify != NULL)
623 notify = notify->
next;
630 while (pstatus != NULL)
634 pstatus = pstatus->
next;
718 const char *
const *
values,
736 const char *
const *
values,
820 const char *
const *
values,
840 true, expand_dbname);
841 if (connOptions == NULL)
958 char **connmember = (
char **) ((
char *)
conn +
option->connofs);
961 *connmember = strdup(tmp);
962 if (*connmember == NULL)
993 const char **tmp = (
const char **) ((
char *) srcConn +
option->connofs);
997 char **dstConnmember = (
char **) ((
char *) dstConn +
option->connofs);
1000 free(*dstConnmember);
1001 *dstConnmember = strdup(*tmp);
1002 if (*dstConnmember == NULL)
1033 if (connOptions == NULL)
1089 char *s = *startptr;
1098 while (*
e !=
'\0' && *
e !=
',')
1100 *more = (*
e ==
',');
1103 p = (
char *)
malloc(
sizeof(
char) * (
len + 1));
1124 struct timeval tval = {0};
1131 rseed = ((uintptr_t)
conn) ^
1133 ((
uint64) tval.tv_usec) ^
1158 "conn->allowed_sasl_mechs[] is not sufficiently large for holding all supported SASL mechanisms");
1277 else if (ch->
host != NULL && ch->
host[0] !=
'\0')
1301 if (ch->
host == NULL)
1329 if (
i == 1 && !more)
1407 if (pwhost == NULL || pwhost[0] ==
'\0')
1428 bool negated =
false;
1438 for (first =
true, more =
true; more; first =
false)
1493 if (strcmp(method,
"password") == 0)
1497 else if (strcmp(method,
"md5") == 0)
1501 else if (strcmp(method,
"gss") == 0)
1506 else if (strcmp(method,
"sspi") == 0)
1518 else if (strcmp(method,
"scram-sha-256") == 0)
1526 else if (strcmp(method,
"none") == 0)
1555 "require_auth", method);
1596 "internal error: no space in allowed_sasl_mechs");
1647 bool allowed =
false;
1666 if (!negated && allowed)
1668 else if (negated && !allowed)
1797 libpq_append_conn_error(
conn,
"weak sslmode \"%s\" may not be used with sslnegotiation=direct (use \"require\", \"verify-ca\", or \"verify-full\")",
1833 "ssl_min_protocol_version",
1841 "ssl_max_protocol_version",
1884#ifndef HAVE_SSL_CTX_SET_CERT_CB
1958 "target_session_attrs",
2029 "load_balance_hosts",
2114 if (connOptions != NULL)
2142 const char *pgtty,
const char *
dbName,
const char *login,
2204 if (pgoptions && pgoptions[0] !=
'\0')
2212 if (login && login[0] !=
'\0')
2220 if (pwd && pwd[0] !=
'\0')
2261 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_NODELAY,
2286 if (addr->ss_family == AF_INET)
2289 &((
struct sockaddr_in *) addr)->sin_addr.s_addr,
2291 host_addr, host_addr_len) == NULL)
2292 host_addr[0] =
'\0';
2294 else if (addr->ss_family == AF_INET6)
2297 &((
struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
2299 host_addr, host_addr_len) == NULL)
2300 host_addr[0] =
'\0';
2303 host_addr[0] =
'\0';
2319 char service[NI_MAXHOST];
2323 service,
sizeof(service),
2326 libpq_gettext(
"connection to server on socket \"%s\" failed: "),
2331 const char *displayed_host;
2332 const char *displayed_port;
2340 if (displayed_port == NULL || displayed_port[0] ==
'\0')
2341 displayed_port = DEF_PGPORT_STR;
2350 strcmp(displayed_host, host_addr) != 0)
2352 libpq_gettext(
"connection to server at \"%s\" (%s), port %s failed: "),
2353 displayed_host, host_addr,
2357 libpq_gettext(
"connection to server at \"%s\", port %s failed: "),
2401 return val != 0 ? 1 : 0;
2422#ifdef PG_TCP_KEEPALIVE_IDLE
2423 if (setsockopt(
conn->
sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
2424 (
char *) &idle,
sizeof(idle)) < 0)
2430 PG_TCP_KEEPALIVE_IDLE_STR,
2451 "keepalives_interval"))
2457 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_KEEPINTVL,
2486 "keepalives_count"))
2492 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_KEEPCNT,
2493 (
char *) &count,
sizeof(count)) < 0)
2508#ifdef SIO_KEEPALIVE_VALS
2518 struct tcp_keepalive ka;
2527 ka.keepalivetime = idle * 1000;
2528 ka.keepaliveinterval =
interval * 1000;
2556 "keepalives_interval"))
2562 "WSAIoctl",
"SIO_KEEPALIVE_VALS",
2583 "tcp_user_timeout"))
2589#ifdef TCP_USER_TIMEOUT
2590 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
2591 (
char *) &timeout,
sizeof(timeout)) < 0)
2620 goto connect_errReturn;
2631 "libpq is incorrectly linked to backend functions\n");
2632 goto connect_errReturn;
2697 int last_whichhost = -2;
2698 int last_whichaddr = -2;
2820 bool reset_connection_state_machine =
false;
2821 bool need_new_connection =
false;
2887 reset_connection_state_machine =
true;
2898 struct addrinfo hint;
2899 struct addrinfo *addrlist;
2942 MemSet(&hint, 0,
sizeof(hint));
2943 hint.ai_socktype = SOCK_STREAM;
2944 hint.ai_family = AF_UNSPEC;
2947 if (ch->
port == NULL || ch->
port[0] ==
'\0')
2948 thisport = DEF_PGPORT;
2954 if (thisport < 1 || thisport > 65535)
2968 if (ret || !addrlist)
2977 hint.ai_flags = AI_NUMERICHOST;
2980 if (ret || !addrlist)
2989 hint.ai_family = AF_UNIX;
3005 if (ret || !addrlist)
3049 reset_connection_state_machine =
true;
3054 if (reset_connection_state_machine)
3067 reset_connection_state_machine =
false;
3068 need_new_connection =
true;
3072 if (need_new_connection)
3089 need_new_connection =
false;
3097#define ENCRYPTION_NEGOTIATION_FAILED(msg) \
3099 switch (encryption_negotiation_failed(conn)) \
3102 libpq_append_conn_error(conn, (msg)); \
3103 goto error_return; \
3105 conn->status = CONNECTION_MADE; \
3106 return PGRES_POLLING_WRITING; \
3108 need_new_connection = true; \
3118#define CONNECTION_FAILED() \
3120 if (connection_failed(conn)) \
3122 need_new_connection = true; \
3126 goto error_return; \
3143 char host_addr[NI_MAXHOST];
3173 "GSSAPI encryption required but it is not supported over a local socket");
3176 if (
conn->gcred == GSS_C_NO_CREDENTIAL)
3181 "GSSAPI encryption required but no credential cache");
3212 sock_type = SOCK_STREAM;
3221 sock_type |= SOCK_CLOEXEC;
3229 sock_type |= SOCK_NONBLOCK;
3268 if (addr_cur->
family != AF_UNIX)
3277#ifndef SOCK_NONBLOCK
3289 if (fcntl(
conn->
sock, F_SETFD, FD_CLOEXEC) == -1)
3299 if (addr_cur->
family != AF_UNIX)
3307 if (usekeepalives < 0)
3312 else if (usekeepalives == 0)
3318 SOL_SOCKET, SO_KEEPALIVE,
3319 (
char *) &on,
sizeof(on)) < 0)
3332#ifdef SIO_KEEPALIVE_VALS
3333 else if (!prepKeepalivesWin32(
conn))
3379 if (setsockopt(
conn->
sock, SOL_SOCKET, SO_NOSIGPIPE,
3380 (
char *) &optval,
sizeof(optval)) == 0)
3445 if (getsockopt(
conn->
sock, SOL_SOCKET, SO_ERROR,
3446 (
char *) &optval, &optlen) == -1)
3452 else if (optval != 0)
3488 char *remote_username;
3500 if (errno == ENOSYS)
3511 if (remote_username == NULL)
3518 free(remote_username);
3521 free(remote_username);
3619 packetlen =
sizeof(cancelpacket);
3715 else if (SSLok ==
'N')
3730 else if (SSLok ==
'E')
3804 else if (rdresult == 0)
3846 else if (gss_ok !=
'G')
3957 (msgLength < 8 || msgLength > 2000))
3963 (msgLength < 8 || msgLength > 2000))
3969#define MAX_ERRLEN 30000
4019 if (avail < msgLength)
4149 "internal error: async authentication has no handler");
4174 "internal error: async cleanup did not release polling socket");
4197 "internal error: async authentication did not set a socket for polling");
4244 const char *sqlstate;
4252 need_new_connection =
true;
4284 bool read_only_server;
4304 "SHOW transaction_read_only"))
4317 read_only_server : !read_only_server)
4362 "SELECT pg_catalog.pg_is_in_recovery()"))
4479 if (strncmp(
val,
"on", 2) == 0)
4501 "SHOW transaction_read_only");
4535 if (strncmp(
val,
"t", 1) == 0)
4551 "SELECT pg_is_in_recovery()");
4564 "invalid connection state %d, probably indicative of memory corruption",
4602 "GSSAPI encryption required but it is not supported over a local socket");
4651#if defined(USE_SSL) || defined(ENABLE_GSS)
4695 int remaining_methods;
4697#define SELECT_NEXT_METHOD(method) \
4699 if ((remaining_methods & method) != 0) \
4701 conn->current_enc_method = method; \
4726 remaining_methods &= ~ENC_GSSAPI;
4731 "GSSAPI encryption required but no credential cache");
4758#undef SELECT_NEXT_METHOD
4845 static bool wsastartup_done =
false;
4847 if (!wsastartup_done)
4851 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
4853 wsastartup_done =
true;