33 #include "pg_config_paths.h"
41 #define _WIN32_IE 0x0500
67 #define LDAP_DEPRECATED 1
69 typedef struct timeval LDAP_TIMEVAL;
76 #define PGPASSFILE ".pgpass"
78 #define PGPASSFILE "pgpass.conf"
87 #define ERRCODE_APPNAME_UNKNOWN "42704"
90 #define ERRCODE_INVALID_PASSWORD "28P01"
92 #define ERRCODE_CANNOT_CONNECT_NOW "57P03"
98 #if defined(TCP_KEEPIDLE)
100 #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
101 #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
102 #elif defined(TCP_KEEPALIVE_THRESHOLD)
104 #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
105 #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
106 #elif defined(TCP_KEEPALIVE) && defined(__darwin__)
109 #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
110 #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
117 #define DefaultHost "localhost"
118 #define DefaultOption ""
120 #define DefaultChannelBinding "prefer"
122 #define DefaultChannelBinding "disable"
124 #define DefaultTargetSessionAttrs "any"
125 #define DefaultLoadBalanceHosts "disable"
127 #define DefaultSSLMode "prefer"
128 #define DefaultSSLCertMode "allow"
130 #define DefaultSSLMode "disable"
131 #define DefaultSSLCertMode "disable"
133 #define DefaultSSLNegotiation "postgres"
136 #define DefaultGSSMode "prefer"
138 #define DefaultGSSMode "disable"
192 {
"service",
"PGSERVICE", NULL, NULL,
193 "Database-Service",
"", 20, -1},
195 {
"user",
"PGUSER", NULL, NULL,
196 "Database-User",
"", 20,
197 offsetof(
struct pg_conn, pguser)},
199 {
"password",
"PGPASSWORD", NULL, NULL,
200 "Database-Password",
"*", 20,
201 offsetof(
struct pg_conn, pgpass)},
203 {
"passfile",
"PGPASSFILE", NULL, NULL,
204 "Database-Password-File",
"", 64,
205 offsetof(
struct pg_conn, pgpassfile)},
208 "Channel-Binding",
"", 8,
209 offsetof(
struct pg_conn, channel_binding)},
211 {
"connect_timeout",
"PGCONNECT_TIMEOUT", NULL, NULL,
212 "Connect-timeout",
"", 10,
213 offsetof(
struct pg_conn, connect_timeout)},
215 {
"dbname",
"PGDATABASE", NULL, NULL,
216 "Database-Name",
"", 20,
219 {
"host",
"PGHOST", NULL, NULL,
220 "Database-Host",
"", 40,
223 {
"hostaddr",
"PGHOSTADDR", NULL, NULL,
224 "Database-Host-IP-Address",
"", 45,
225 offsetof(
struct pg_conn, pghostaddr)},
227 {
"port",
"PGPORT", DEF_PGPORT_STR, NULL,
228 "Database-Port",
"", 6,
231 {
"client_encoding",
"PGCLIENTENCODING", NULL, NULL,
232 "Client-Encoding",
"", 10,
233 offsetof(
struct pg_conn, client_encoding_initial)},
236 "Backend-Options",
"", 40,
237 offsetof(
struct pg_conn, pgoptions)},
239 {
"application_name",
"PGAPPNAME", NULL, NULL,
240 "Application-Name",
"", 64,
241 offsetof(
struct pg_conn, appname)},
243 {
"fallback_application_name", NULL, NULL, NULL,
244 "Fallback-Application-Name",
"", 64,
245 offsetof(
struct pg_conn, fbappname)},
247 {
"keepalives", NULL, NULL, NULL,
248 "TCP-Keepalives",
"", 1,
249 offsetof(
struct pg_conn, keepalives)},
251 {
"keepalives_idle", NULL, NULL, NULL,
252 "TCP-Keepalives-Idle",
"", 10,
253 offsetof(
struct pg_conn, keepalives_idle)},
255 {
"keepalives_interval", NULL, NULL, NULL,
256 "TCP-Keepalives-Interval",
"", 10,
257 offsetof(
struct pg_conn, keepalives_interval)},
259 {
"keepalives_count", NULL, NULL, NULL,
260 "TCP-Keepalives-Count",
"", 10,
261 offsetof(
struct pg_conn, keepalives_count)},
263 {
"tcp_user_timeout", NULL, NULL, NULL,
264 "TCP-User-Timeout",
"", 10,
265 offsetof(
struct pg_conn, pgtcp_user_timeout)},
275 offsetof(
struct pg_conn, sslmode)},
278 "SSL-Negotiation",
"", 9,
279 offsetof(
struct pg_conn, sslnegotiation)},
281 {
"sslcompression",
"PGSSLCOMPRESSION",
"0", NULL,
282 "SSL-Compression",
"", 1,
283 offsetof(
struct pg_conn, sslcompression)},
285 {
"sslcert",
"PGSSLCERT", NULL, NULL,
286 "SSL-Client-Cert",
"", 64,
287 offsetof(
struct pg_conn, sslcert)},
289 {
"sslkey",
"PGSSLKEY", NULL, NULL,
290 "SSL-Client-Key",
"", 64,
291 offsetof(
struct pg_conn, sslkey)},
293 {
"sslcertmode",
"PGSSLCERTMODE", NULL, NULL,
294 "SSL-Client-Cert-Mode",
"", 8,
295 offsetof(
struct pg_conn, sslcertmode)},
297 {
"sslpassword", NULL, NULL, NULL,
298 "SSL-Client-Key-Password",
"*", 20,
299 offsetof(
struct pg_conn, sslpassword)},
301 {
"sslrootcert",
"PGSSLROOTCERT", NULL, NULL,
302 "SSL-Root-Certificate",
"", 64,
303 offsetof(
struct pg_conn, sslrootcert)},
305 {
"sslcrl",
"PGSSLCRL", NULL, NULL,
306 "SSL-Revocation-List",
"", 64,
307 offsetof(
struct pg_conn, sslcrl)},
309 {
"sslcrldir",
"PGSSLCRLDIR", NULL, NULL,
310 "SSL-Revocation-List-Dir",
"", 64,
311 offsetof(
struct pg_conn, sslcrldir)},
313 {
"sslsni",
"PGSSLSNI",
"1", NULL,
315 offsetof(
struct pg_conn, sslsni)},
317 {
"requirepeer",
"PGREQUIREPEER", NULL, NULL,
318 "Require-Peer",
"", 10,
319 offsetof(
struct pg_conn, requirepeer)},
321 {
"require_auth",
"PGREQUIREAUTH", NULL, NULL,
322 "Require-Auth",
"", 14,
323 offsetof(
struct pg_conn, require_auth)},
325 {
"ssl_min_protocol_version",
"PGSSLMINPROTOCOLVERSION",
"TLSv1.2", NULL,
326 "SSL-Minimum-Protocol-Version",
"", 8,
329 {
"ssl_max_protocol_version",
"PGSSLMAXPROTOCOLVERSION", NULL, NULL,
330 "SSL-Maximum-Protocol-Version",
"", 8,
338 "GSSENC-Mode",
"", 8,
339 offsetof(
struct pg_conn, gssencmode)},
342 {
"krbsrvname",
"PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
343 "Kerberos-service-name",
"", 20,
344 offsetof(
struct pg_conn, krbsrvname)},
346 {
"gsslib",
"PGGSSLIB", NULL, NULL,
347 "GSS-library",
"", 7,
348 offsetof(
struct pg_conn, gsslib)},
350 {
"gssdelegation",
"PGGSSDELEGATION",
"0", NULL,
351 "GSS-delegation",
"", 1,
352 offsetof(
struct pg_conn, gssdelegation)},
354 {
"replication", NULL, NULL, NULL,
355 "Replication",
"D", 5,
356 offsetof(
struct pg_conn, replication)},
358 {
"target_session_attrs",
"PGTARGETSESSIONATTRS",
360 "Target-Session-Attrs",
"", 15,
361 offsetof(
struct pg_conn, target_session_attrs)},
363 {
"load_balance_hosts",
"PGLOADBALANCEHOSTS",
365 "Load-Balance-Hosts",
"", 8,
366 offsetof(
struct pg_conn, load_balance_hosts)},
369 {NULL, NULL, NULL, NULL,
377 "PGDATESTYLE",
"datestyle"
397 #if defined(USE_SSL) || defined(ENABLE_GSS)
398 static int encryption_negotiation_failed(
PGconn *
conn);
418 bool use_defaults,
int expand_dbname);
431 const char *keyword);
433 const char *keyword,
const char *
value,
434 PQExpBuffer errorMessage,
bool ignoreMissing,
bool uri_decode);
436 const char *keyword);
448 const char *
username,
const char *pgpassfile);
500 if (
conn->gcred != GSS_C_NO_CREDENTIAL)
502 gss_release_cred(&min_s, &
conn->gcred);
503 conn->gcred = GSS_C_NO_CREDENTIAL;
506 gss_delete_sec_context(&min_s, &
conn->gctx, GSS_C_NO_BUFFER);
508 gss_release_name(&min_s, &
conn->gtarg_nam);
509 if (
conn->gss_SendBuffer)
512 conn->gss_SendBuffer = NULL;
514 if (
conn->gss_RecvBuffer)
517 conn->gss_RecvBuffer = NULL;
519 if (
conn->gss_ResultBuffer)
522 conn->gss_ResultBuffer = NULL;
524 conn->gssenc =
false;
528 if (
conn->sspitarget)
531 conn->sspitarget = NULL;
535 FreeCredentialsHandle(
conn->sspicred);
537 conn->sspicred = NULL;
541 DeleteSecurityContext(
conn->sspictx);
543 conn->sspictx = NULL;
561 while (queue != NULL)
592 while (notify != NULL)
596 notify = notify->
next;
603 while (pstatus != NULL)
607 pstatus = pstatus->
next;
691 const char *
const *
values,
709 const char *
const *
values,
793 const char *
const *
values,
813 true, expand_dbname);
814 if (connOptions == NULL)
931 char **connmember = (
char **) ((
char *)
conn +
option->connofs);
934 *connmember = strdup(tmp);
935 if (*connmember == NULL)
966 const char **tmp = (
const char **) ((
char *) srcConn +
option->connofs);
970 char **dstConnmember = (
char **) ((
char *) dstConn +
option->connofs);
973 free(*dstConnmember);
974 *dstConnmember = strdup(*tmp);
975 if (*dstConnmember == NULL)
1006 if (connOptions == NULL)
1062 char *s = *startptr;
1071 while (*
e !=
'\0' && *
e !=
',')
1073 *more = (*
e ==
',');
1076 p = (
char *)
malloc(
sizeof(
char) * (
len + 1));
1097 struct timeval tval = {0};
1104 rseed = ((uintptr_t)
conn) ^
1105 ((uint64) getpid()) ^
1106 ((uint64) tval.tv_usec) ^
1107 ((uint64) tval.tv_sec);
1199 else if (ch->
host != NULL && ch->
host[0] !=
'\0')
1223 if (ch->
host == NULL)
1251 if (
i == 1 && !more)
1329 if (pwhost == NULL || pwhost[0] ==
'\0')
1350 bool negated =
false;
1359 for (first =
true, more =
true; more; first =
false)
1408 if (strcmp(method,
"password") == 0)
1412 else if (strcmp(method,
"md5") == 0)
1416 else if (strcmp(method,
"gss") == 0)
1421 else if (strcmp(method,
"sspi") == 0)
1426 else if (strcmp(method,
"scram-sha-256") == 0)
1433 else if (strcmp(method,
"none") == 0)
1462 "require_auth", method);
1626 libpq_append_conn_error(
conn,
"weak sslmode \"%s\" may not be used with sslnegotiation=direct (use \"require\", \"verify-ca\", or \"verify-full\")",
1662 "ssl_min_protocol_version",
1670 "ssl_max_protocol_version",
1713 #ifndef HAVE_SSL_CTX_SET_CERT_CB
1787 "target_session_attrs",
1808 "load_balance_hosts",
1893 if (connOptions != NULL)
1921 const char *pgtty,
const char *
dbName,
const char *login,
1983 if (pgoptions && pgoptions[0] !=
'\0')
1991 if (login && login[0] !=
'\0')
1999 if (pwd && pwd[0] !=
'\0')
2040 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_NODELAY,
2065 if (addr->ss_family == AF_INET)
2068 &((
struct sockaddr_in *) addr)->sin_addr.s_addr,
2070 host_addr, host_addr_len) == NULL)
2071 host_addr[0] =
'\0';
2073 else if (addr->ss_family == AF_INET6)
2076 &((
struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
2078 host_addr, host_addr_len) == NULL)
2079 host_addr[0] =
'\0';
2082 host_addr[0] =
'\0';
2098 char service[NI_MAXHOST];
2102 service,
sizeof(service),
2105 libpq_gettext(
"connection to server on socket \"%s\" failed: "),
2110 const char *displayed_host;
2111 const char *displayed_port;
2119 if (displayed_port == NULL || displayed_port[0] ==
'\0')
2120 displayed_port = DEF_PGPORT_STR;
2129 strcmp(displayed_host, host_addr) != 0)
2131 libpq_gettext(
"connection to server at \"%s\" (%s), port %s failed: "),
2132 displayed_host, host_addr,
2136 libpq_gettext(
"connection to server at \"%s\", port %s failed: "),
2180 return val != 0 ? 1 : 0;
2201 #ifdef PG_TCP_KEEPALIVE_IDLE
2202 if (setsockopt(
conn->
sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
2203 (
char *) &idle,
sizeof(idle)) < 0)
2209 PG_TCP_KEEPALIVE_IDLE_STR,
2230 "keepalives_interval"))
2235 #ifdef TCP_KEEPINTVL
2236 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_KEEPINTVL,
2265 "keepalives_count"))
2271 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_KEEPCNT,
2272 (
char *) &count,
sizeof(count)) < 0)
2287 #ifdef SIO_KEEPALIVE_VALS
2297 struct tcp_keepalive ka;
2306 ka.keepalivetime = idle * 1000;
2307 ka.keepaliveinterval =
interval * 1000;
2335 "keepalives_interval"))
2341 "WSAIoctl",
"SIO_KEEPALIVE_VALS",
2362 "tcp_user_timeout"))
2368 #ifdef TCP_USER_TIMEOUT
2369 if (setsockopt(
conn->
sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
2370 (
char *) &timeout,
sizeof(timeout)) < 0)
2399 goto connect_errReturn;
2410 "libpq is incorrectly linked to backend functions\n");
2411 goto connect_errReturn;
2476 int last_whichhost = -2;
2477 int last_whichaddr = -2;
2599 bool reset_connection_state_machine =
false;
2600 bool need_new_connection =
false;
2665 reset_connection_state_machine =
true;
2676 struct addrinfo hint;
2677 struct addrinfo *addrlist;
2720 MemSet(&hint, 0,
sizeof(hint));
2721 hint.ai_socktype = SOCK_STREAM;
2722 hint.ai_family = AF_UNSPEC;
2725 if (ch->
port == NULL || ch->
port[0] ==
'\0')
2726 thisport = DEF_PGPORT;
2732 if (thisport < 1 || thisport > 65535)
2746 if (ret || !addrlist)
2755 hint.ai_flags = AI_NUMERICHOST;
2758 if (ret || !addrlist)
2767 hint.ai_family = AF_UNIX;
2783 if (ret || !addrlist)
2827 reset_connection_state_machine =
true;
2832 if (reset_connection_state_machine)
2845 reset_connection_state_machine =
false;
2846 need_new_connection =
true;
2850 if (need_new_connection)
2867 need_new_connection =
false;
2875 #define ENCRYPTION_NEGOTIATION_FAILED(msg) \
2877 switch (encryption_negotiation_failed(conn)) \
2880 libpq_append_conn_error(conn, (msg)); \
2881 goto error_return; \
2883 conn->status = CONNECTION_MADE; \
2884 return PGRES_POLLING_WRITING; \
2886 need_new_connection = true; \
2896 #define CONNECTION_FAILED() \
2898 if (connection_failed(conn)) \
2900 need_new_connection = true; \
2904 goto error_return; \
2921 char host_addr[NI_MAXHOST];
2951 "GSSAPI encryption required but it is not supported over a local socket");
2954 if (
conn->gcred == GSS_C_NO_CREDENTIAL)
2959 "GSSAPI encryption required but no credential cache");
2990 sock_type = SOCK_STREAM;
2999 sock_type |= SOCK_CLOEXEC;
3001 #ifdef SOCK_NONBLOCK
3007 sock_type |= SOCK_NONBLOCK;
3046 if (addr_cur->
family != AF_UNIX)
3055 #ifndef SOCK_NONBLOCK
3065 #ifndef SOCK_CLOEXEC
3067 if (fcntl(
conn->
sock, F_SETFD, FD_CLOEXEC) == -1)
3077 if (addr_cur->
family != AF_UNIX)
3085 if (usekeepalives < 0)
3090 else if (usekeepalives == 0)
3096 SOL_SOCKET, SO_KEEPALIVE,
3097 (
char *) &on,
sizeof(on)) < 0)
3110 #ifdef SIO_KEEPALIVE_VALS
3111 else if (!prepKeepalivesWin32(
conn))
3157 if (setsockopt(
conn->
sock, SOL_SOCKET, SO_NOSIGPIPE,
3158 (
char *) &optval,
sizeof(optval)) == 0)
3223 if (getsockopt(
conn->
sock, SOL_SOCKET, SO_ERROR,
3224 (
char *) &optval, &optlen) == -1)
3230 else if (optval != 0)
3266 char *remote_username;
3278 if (errno == ENOSYS)
3289 if (remote_username == NULL)
3296 free(remote_username);
3299 free(remote_username);
3397 packetlen =
sizeof(cancelpacket);
3493 else if (SSLok ==
'N')
3508 else if (SSLok ==
'E')
3592 else if (rdresult == 0)
3638 else if (gss_ok !=
'G')
3748 (msgLength < 8 || msgLength > 2000))
3754 (msgLength < 8 || msgLength > 2000))
3760 #define MAX_ERRLEN 30000
3810 if (avail < msgLength)
3962 const char *sqlstate;
3970 need_new_connection =
true;
4002 bool read_only_server;
4022 "SHOW transaction_read_only"))
4035 read_only_server : !read_only_server)
4080 "SELECT pg_catalog.pg_is_in_recovery()"))
4197 if (strncmp(
val,
"on", 2) == 0)
4219 "SHOW transaction_read_only");
4253 if (strncmp(
val,
"t", 1) == 0)
4269 "SELECT pg_is_in_recovery()");
4282 "invalid connection state %d, probably indicative of memory corruption",
4320 "GSSAPI encryption required but it is not supported over a local socket");
4369 #if defined(USE_SSL) || defined(ENABLE_GSS)
4413 int remaining_methods;
4415 #define SELECT_NEXT_METHOD(method) \
4417 if ((remaining_methods & method) != 0) \
4419 conn->current_enc_method = method; \
4449 "GSSAPI encryption required but no credential cache");
4476 #undef SELECT_NEXT_METHOD
4563 static bool wsastartup_done =
false;
4565 if (!wsastartup_done)
4569 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
4571 wsastartup_done =
true;
4762 struct addrinfo *ai = addrlist;
5002 const void *
buf,
size_t buf_len)
5025 #define LDAP_URL "ldap://"
5026 #define LDAP_DEF_PORT 389
5027 #define PGLDAP_TIMEOUT 2
5029 #define ld_is_sp_tab(x) ((x) == ' ' || (x) == '\t')
5030 #define ld_is_nl_cr(x) ((x) == '\r' || (x) == '\n')
5056 int port = LDAP_DEF_PORT,
5079 char *attrs[2] = {NULL, NULL};
5084 LDAP_TIMEVAL time = {PGLDAP_TIMEOUT, 0};
5086 if ((url = strdup(purl)) == NULL)
5101 "invalid LDAP URL \"%s\": scheme must be ldap://", purl);
5112 p = strchr(url + strlen(LDAP_URL),
'/');
5113 if (p == NULL || *(p + 1) ==
'\0' || *(p + 1) ==
'?')
5116 "invalid LDAP URL \"%s\": missing distinguished name",
5125 if ((p = strchr(dn,
'?')) == NULL || *(p + 1) ==
'\0' || *(p + 1) ==
'?')
5128 "invalid LDAP URL \"%s\": must have exactly one attribute",
5137 if ((p = strchr(attrs[0],
'?')) == NULL || *(p + 1) ==
'\0' || *(p + 1) ==
'?')
5140 "invalid LDAP URL \"%s\": must have search scope (base/one/sub)",
5149 if ((p = strchr(scopestr,
'?')) == NULL || *(p + 1) ==
'\0' || *(p + 1) ==
'?')
5152 "invalid LDAP URL \"%s\": no filter",
5159 if ((p = strchr(filter,
'?')) != NULL)
5163 if ((p1 = strchr(
hostname,
':')) != NULL)
5170 lport = strtol(
portstr, &endptr, 10);
5171 if (*
portstr ==
'\0' || *endptr !=
'\0' || errno || lport < 0 || lport > 65535)
5174 "invalid LDAP URL \"%s\": invalid port number",
5183 if (strchr(attrs[0],
',') != NULL)
5186 "invalid LDAP URL \"%s\": must have exactly one attribute",
5194 scope = LDAP_SCOPE_BASE;
5196 scope = LDAP_SCOPE_ONELEVEL;
5198 scope = LDAP_SCOPE_SUBTREE;
5202 "invalid LDAP URL \"%s\": must have search scope (base/one/sub)",
5230 if (ldap_connect(ld, &time) != LDAP_SUCCESS)
5239 if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
5247 if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1)
5257 if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &
res)) == -1 ||
5271 if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
5281 if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &
res))
5286 libpq_append_error(errorMessage,
"lookup on LDAP server failed: %s", ldap_err2string(rc));
5293 if ((rc = ldap_count_entries(ld,
res)) != 1)
5306 if ((entry = ldap_first_entry(ld,
res)) == NULL)
5317 if ((
values = ldap_get_values_len(ld, entry, attrs[0])) == NULL)
5332 ldap_value_free_len(
values);
5344 ldap_value_free_len(
values);
5357 ldap_value_free_len(
values);
5361 oldstate =
state = 0;
5362 for (p = result; *p !=
'\0'; ++p)
5367 if (!ld_is_sp_tab(*p) && !ld_is_nl_cr(*p))
5374 if (ld_is_sp_tab(*p))
5379 else if (ld_is_nl_cr(*p))
5382 "missing \"=\" after \"%s\" in connection info string",
5398 else if (!ld_is_sp_tab(*p))
5401 "missing \"=\" after \"%s\" in connection info string",
5414 else if (ld_is_nl_cr(*p))
5416 optval = optname + strlen(optname);
5419 else if (!ld_is_sp_tab(*p))
5426 if (ld_is_sp_tab(*p) || ld_is_nl_cr(*