60 const char **logdetail);
68#define IDENT_USERNAME_MAX 512
88#ifdef HAVE_PAM_PAM_APPL_H
89#include <pam/pam_appl.h>
91#ifdef HAVE_SECURITY_PAM_APPL_H
92#include <security/pam_appl.h>
95#define PGSQL_PAM_SERVICE "postgresql"
98static int pam_passwd_conv_proc(
int num_msg,
const struct pam_message **msg,
99 struct pam_response **resp,
void *appdata_ptr);
101static struct pam_conv pam_passw_conv = {
102 &pam_passwd_conv_proc,
106static const char *pam_passwd = NULL;
108static Port *pam_port_cludge;
110static bool pam_no_password;
132#define LDAP_DEPRECATED 1
139static int CheckLDAPAuth(
Port *
port);
142#ifndef LDAP_OPT_DIAGNOSTIC_MESSAGE
143#define LDAP_OPT_DIAGNOSTIC_MESSAGE LDAP_OPT_ERROR_STRING
147static char *dummy_ldap_password_mutator(
char *
input);
157static int CheckCertAuth(
Port *
port);
177static int pg_GSS_checkauth(
Port *
port);
178static int pg_GSS_recvauth(
Port *
port);
187typedef SECURITY_STATUS
188 (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) (PCtxtHandle,
void **);
189static int pg_SSPI_recvauth(
Port *
port);
190static int pg_SSPI_make_upn(
char *accountname,
191 size_t accountnamesize,
193 size_t domainnamesize,
194 bool update_accountname);
202static int PerformRadiusTransaction(
const char *server,
const char *secret,
const char *
portstr,
const char *identifier,
const char *user_name,
const char *passwd);
235 int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
250 switch (
port->hba->auth_method)
254 errstr =
gettext_noop(
"authentication failed for user \"%s\": host rejected");
257 errstr =
gettext_noop(
"\"trust\" authentication failed for user \"%s\"");
260 errstr =
gettext_noop(
"Ident authentication failed for user \"%s\"");
263 errstr =
gettext_noop(
"Peer authentication failed for user \"%s\"");
268 errstr =
gettext_noop(
"password authentication failed for user \"%s\"");
273 errstr =
gettext_noop(
"GSSAPI authentication failed for user \"%s\"");
276 errstr =
gettext_noop(
"SSPI authentication failed for user \"%s\"");
279 errstr =
gettext_noop(
"PAM authentication failed for user \"%s\"");
282 errstr =
gettext_noop(
"BSD authentication failed for user \"%s\"");
285 errstr =
gettext_noop(
"LDAP authentication failed for user \"%s\"");
288 errstr =
gettext_noop(
"certificate authentication failed for user \"%s\"");
291 errstr =
gettext_noop(
"RADIUS authentication failed for user \"%s\"");
294 errstr =
gettext_noop(
"OAuth bearer authentication failed for user \"%s\"");
297 errstr =
gettext_noop(
"authentication failed for user \"%s\": invalid authentication method");
301 cdetail =
psprintf(
_(
"Connection matched file \"%s\" line %d: \"%s\""),
302 port->hba->sourcefile,
port->hba->linenumber,
305 logdetail =
psprintf(
"%s\n%s", logdetail, cdetail);
346 (
errmsg(
"authentication identifier set more than once"),
347 errdetail_log(
"previous identifier: \"%s\"; new identifier: \"%s\"",
357 errmsg(
"connection authenticated: identity=\"%s\" method=%s "
361 port->hba->sourcefile,
port->hba->linenumber));
374 const char *logdetail = NULL;
396 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
397 errmsg(
"client certificates can only be checked if a root certificate store is available")));
405 if (!
port->peer_cert_valid)
407 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
408 errmsg(
"connection requires a valid client certificate")));
414 switch (
port->hba->auth_method)
429 char hostinfo[NI_MAXHOST];
430 const char *encryption_state;
433 hostinfo,
sizeof(hostinfo),
439 (
port->gss &&
port->gss->enc) ?
_(
"GSS encryption") :
442 port->ssl_in_use ?
_(
"SSL encryption") :
448 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
450 errmsg(
"pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
451 hostinfo,
port->user_name,
455 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
457 errmsg(
"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
458 hostinfo,
port->user_name,
475 char hostinfo[NI_MAXHOST];
476 const char *encryption_state;
479 hostinfo,
sizeof(hostinfo),
485 (
port->gss &&
port->gss->enc) ?
_(
"GSS encryption") :
488 port->ssl_in_use ?
_(
"SSL encryption") :
492#define HOSTNAME_LOOKUP_DETAIL(port) \
493 (port->remote_hostname ? \
494 (port->remote_hostname_resolv == +1 ? \
495 errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
496 port->remote_hostname) : \
497 port->remote_hostname_resolv == 0 ? \
498 errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
499 port->remote_hostname) : \
500 port->remote_hostname_resolv == -1 ? \
501 errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
502 port->remote_hostname) : \
503 port->remote_hostname_resolv == -2 ? \
504 errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
505 port->remote_hostname, \
506 gai_strerror(port->remote_hostname_errcode)) : \
508 : (port->remote_hostname_resolv == -2 ? \
509 errdetail_log("Could not resolve client IP address to a host name: %s.", \
510 gai_strerror(port->remote_hostname_errcode)) : \
515 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
517 errmsg(
"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
518 hostinfo,
port->user_name,
523 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
525 errmsg(
"no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
526 hostinfo,
port->user_name,
536 if (
port->gss == NULL)
537 port->gss = (pg_gssinfo *)
540 port->gss->auth =
true;
547 status = pg_GSS_checkauth(
port);
551 status = pg_GSS_recvauth(
port);
560 if (
port->gss == NULL)
561 port->gss = (pg_gssinfo *)
565 status = pg_SSPI_recvauth(
port);
590 status = CheckPAMAuth(
port,
port->user_name,
"");
598 status = CheckBSDAuth(
port,
port->user_name);
606 status = CheckLDAPAuth(
port);
632 status = CheckCertAuth(
port);
649 errmsg(
"connection authenticated: user=\"%s\" method=%s "
652 port->hba->sourcefile,
port->hba->linenumber));
656 (*ClientAuthentication_hook) (
port, status);
717 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
718 errmsg(
"expected password response, got message type %d",
736 if (strlen(
buf.data) + 1 !=
buf.len)
738 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
739 errmsg(
"invalid password packet size")));
757 errmsg(
"empty password returned by client")));
885 (
errmsg(
"could not generate random MD5 salt")));
897 md5Salt, 4, logdetail);
921 gss_buffer_desc gbuf;
922 gss_cred_id_t delegated_creds;
935 (
errcode(ERRCODE_OUT_OF_MEMORY),
936 errmsg(
"could not set environment: %m")));
946 port->gss->cred = GSS_C_NO_CREDENTIAL;
951 port->gss->ctx = GSS_C_NO_CONTEXT;
953 delegated_creds = GSS_C_NO_CREDENTIAL;
954 port->gss->delegated_creds =
false;
974 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
975 errmsg(
"expected GSS response, got message type %d",
990 gbuf.length =
buf.len;
991 gbuf.value =
buf.data;
993 elog(
DEBUG4,
"processing received GSS token of length %u",
994 (
unsigned int) gbuf.length);
996 maj_stat = gss_accept_sec_context(&min_stat,
1000 GSS_C_NO_CHANNEL_BINDINGS,
1011 elog(
DEBUG5,
"gss_accept_sec_context major: %u, "
1012 "minor: %u, outlen: %u, outflags: %x",
1014 (
unsigned int)
port->gss->outbuf.length, gflags);
1018 if (delegated_creds != GSS_C_NO_CREDENTIAL && gflags & GSS_C_DELEG_FLAG)
1021 port->gss->delegated_creds =
true;
1024 if (
port->gss->outbuf.length != 0)
1029 elog(
DEBUG4,
"sending GSS response token of length %u",
1030 (
unsigned int)
port->gss->outbuf.length);
1033 port->gss->outbuf.value,
port->gss->outbuf.length);
1035 gss_release_buffer(&lmin_s, &
port->gss->outbuf);
1038 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
1040 gss_delete_sec_context(&lmin_s, &
port->gss->ctx, GSS_C_NO_BUFFER);
1042 maj_stat, min_stat);
1046 if (maj_stat == GSS_S_CONTINUE_NEEDED)
1049 }
while (maj_stat == GSS_S_CONTINUE_NEEDED);
1051 if (
port->gss->cred != GSS_C_NO_CREDENTIAL)
1056 gss_release_cred(&min_stat, &
port->gss->cred);
1058 return pg_GSS_checkauth(
port);
1072 gss_buffer_desc gbuf;
1079 maj_stat = gss_display_name(&min_stat,
port->gss->name, &gbuf, NULL);
1080 if (maj_stat != GSS_S_COMPLETE)
1083 maj_stat, min_stat);
1091 princ =
palloc(gbuf.length + 1);
1092 memcpy(princ, gbuf.value, gbuf.length);
1093 princ[gbuf.length] =
'\0';
1094 gss_release_buffer(&lmin_s, &gbuf);
1110 if (strchr(princ,
'@'))
1112 char *cp = strchr(princ,
'@');
1119 if (!
port->hba->include_realm)
1123 if (
port->hba->krb_realm != NULL && strlen(
port->hba->krb_realm))
1131 ret = strcmp(
port->hba->krb_realm, cp);
1137 "GSSAPI realm (%s) and configured realm (%s) don't match",
1138 cp,
port->hba->krb_realm);
1144 else if (
port->hba->krb_realm && strlen(
port->hba->krb_realm))
1147 "GSSAPI did not return realm but realm matching was requested");
1173pg_SSPI_error(
int severity,
const char *
errmsg, SECURITY_STATUS r)
1177 if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
1178 FORMAT_MESSAGE_FROM_SYSTEM,
1180 sysmsg,
sizeof(sysmsg), NULL) == 0)
1196 CredHandle sspicred;
1197 CtxtHandle *sspictx = NULL,
1201 SecBufferDesc inbuf;
1202 SecBufferDesc outbuf;
1203 SecBuffer OutBuffers[1];
1204 SecBuffer InBuffers[1];
1206 TOKEN_USER *tokenuser;
1210 DWORD accountnamesize =
sizeof(accountname);
1211 DWORD domainnamesize =
sizeof(domainname);
1212 SID_NAME_USE accountnameuse;
1218 r = AcquireCredentialsHandle(NULL,
1220 SECPKG_CRED_INBOUND,
1228 pg_SSPI_error(
ERROR,
_(
"could not acquire SSPI credentials"), r);
1242 if (sspictx != NULL)
1244 DeleteSecurityContext(sspictx);
1247 FreeCredentialsHandle(&sspicred);
1252 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
1253 errmsg(
"expected SSPI response, got message type %d",
1264 if (sspictx != NULL)
1266 DeleteSecurityContext(sspictx);
1269 FreeCredentialsHandle(&sspicred);
1274 inbuf.ulVersion = SECBUFFER_VERSION;
1276 inbuf.pBuffers = InBuffers;
1277 InBuffers[0].pvBuffer =
buf.data;
1278 InBuffers[0].cbBuffer =
buf.len;
1279 InBuffers[0].BufferType = SECBUFFER_TOKEN;
1282 OutBuffers[0].pvBuffer = NULL;
1283 OutBuffers[0].BufferType = SECBUFFER_TOKEN;
1284 OutBuffers[0].cbBuffer = 0;
1285 outbuf.cBuffers = 1;
1286 outbuf.pBuffers = OutBuffers;
1287 outbuf.ulVersion = SECBUFFER_VERSION;
1289 elog(
DEBUG4,
"processing received SSPI token of length %u",
1290 (
unsigned int)
buf.len);
1292 r = AcceptSecurityContext(&sspicred,
1295 ASC_REQ_ALLOCATE_MEMORY,
1296 SECURITY_NETWORK_DREP,
1305 if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
1310 elog(
DEBUG4,
"sending SSPI response token of length %u",
1311 (
unsigned int) outbuf.pBuffers[0].cbBuffer);
1313 port->gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
1314 port->gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;
1317 port->gss->outbuf.value,
port->gss->outbuf.length);
1319 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
1322 if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
1324 if (sspictx != NULL)
1326 DeleteSecurityContext(sspictx);
1329 FreeCredentialsHandle(&sspicred);
1330 pg_SSPI_error(
ERROR,
1331 _(
"could not accept SSPI security context"), r);
1340 if (sspictx == NULL)
1342 sspictx =
malloc(
sizeof(CtxtHandle));
1343 if (sspictx == NULL)
1345 (
errmsg(
"out of memory")));
1348 memcpy(sspictx, &newctx,
sizeof(CtxtHandle));
1350 if (r == SEC_I_CONTINUE_NEEDED)
1353 }
while (r == SEC_I_CONTINUE_NEEDED);
1359 FreeCredentialsHandle(&sspicred);
1369 r = QuerySecurityContextToken(sspictx, &
token);
1371 pg_SSPI_error(
ERROR,
1372 _(
"could not get token from SSPI security context"), r);
1378 DeleteSecurityContext(sspictx);
1381 if (!GetTokenInformation(
token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
1383 (
errmsg_internal(
"could not get token information buffer size: error code %lu",
1386 tokenuser =
malloc(retlen);
1387 if (tokenuser == NULL)
1389 (
errmsg(
"out of memory")));
1391 if (!GetTokenInformation(
token, TokenUser, tokenuser, retlen, &retlen))
1398 if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
1399 domainname, &domainnamesize, &accountnameuse))
1406 if (!
port->hba->compat_realm)
1408 int status = pg_SSPI_make_upn(accountname,
sizeof(accountname),
1409 domainname,
sizeof(domainname),
1410 port->hba->upn_username);
1423 if (
port->hba->compat_realm)
1441 if (
port->hba->krb_realm && strlen(
port->hba->krb_realm))
1446 "SSPI domain (%s) and configured domain (%s) don't match",
1447 domainname,
port->hba->krb_realm);
1459 if (
port->hba->include_realm)
1464 namebuf =
psprintf(
"%s@%s", accountname, domainname);
1478pg_SSPI_make_upn(
char *accountname,
1479 size_t accountnamesize,
1481 size_t domainnamesize,
1482 bool update_accountname)
1485 char *upname = NULL;
1487 ULONG upnamesize = 0;
1488 size_t upnamerealmsize;
1498 samname =
psprintf(
"%s\\%s", domainname, accountname);
1499 res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
1502 if ((!res && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1507 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1508 errmsg(
"could not translate name")));
1513 upname =
palloc(upnamesize);
1515 res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
1516 upname, &upnamesize);
1520 p = strchr(upname,
'@');
1522 if (!res || p == NULL)
1526 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1527 errmsg(
"could not translate name")));
1532 upnamerealmsize = upnamesize - (p - upname + 1);
1535 if (upnamerealmsize > domainnamesize)
1539 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1540 errmsg(
"realm name too long")));
1545 strcpy(domainname, p + 1);
1548 if (update_accountname)
1550 if ((p - upname + 1) > accountnamesize)
1554 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1555 errmsg(
"translated account name too long")));
1560 strcpy(accountname, upname);
1585 const char *
cursor = ident_response;
1590 if (strlen(ident_response) < 2)
1592 else if (ident_response[strlen(ident_response) - 2] !=
'\r')
1604 char response_type[80];
1612 i < (
int) (
sizeof(response_type) - 1))
1613 response_type[
i++] = *
cursor++;
1614 response_type[
i] =
'\0';
1617 if (strcmp(response_type,
"USERID") != 0)
1644 ident_user[
i] =
'\0';
1671 char remote_addr_s[NI_MAXHOST];
1672 char remote_port[NI_MAXSERV];
1673 char local_addr_s[NI_MAXHOST];
1674 char local_port[NI_MAXSERV];
1675 char ident_port[NI_MAXSERV];
1676 char ident_query[80];
1678 struct addrinfo *ident_serv = NULL,
1687 remote_addr_s,
sizeof(remote_addr_s),
1688 remote_port,
sizeof(remote_port),
1689 NI_NUMERICHOST | NI_NUMERICSERV);
1691 local_addr_s,
sizeof(local_addr_s),
1692 local_port,
sizeof(local_port),
1693 NI_NUMERICHOST | NI_NUMERICSERV);
1696 hints.ai_flags = AI_NUMERICHOST;
1697 hints.ai_family = remote_addr.
addr.ss_family;
1698 hints.ai_socktype = SOCK_STREAM;
1699 hints.ai_protocol = 0;
1700 hints.ai_addrlen = 0;
1701 hints.ai_canonname = NULL;
1702 hints.ai_addr = NULL;
1703 hints.ai_next = NULL;
1705 if (rc || !ident_serv)
1708 ident_return =
false;
1709 goto ident_inet_done;
1712 hints.ai_flags = AI_NUMERICHOST;
1713 hints.ai_family = local_addr.
addr.ss_family;
1714 hints.ai_socktype = SOCK_STREAM;
1715 hints.ai_protocol = 0;
1716 hints.ai_addrlen = 0;
1717 hints.ai_canonname = NULL;
1718 hints.ai_addr = NULL;
1719 hints.ai_next = NULL;
1724 ident_return =
false;
1725 goto ident_inet_done;
1728 sock_fd =
socket(ident_serv->ai_family, ident_serv->ai_socktype,
1729 ident_serv->ai_protocol);
1734 errmsg(
"could not create socket for Ident connection: %m")));
1735 ident_return =
false;
1736 goto ident_inet_done;
1744 rc =
bind(sock_fd, la->ai_addr, la->ai_addrlen);
1749 errmsg(
"could not bind to local address \"%s\": %m",
1751 ident_return =
false;
1752 goto ident_inet_done;
1755 rc =
connect(sock_fd, ident_serv->ai_addr,
1756 ident_serv->ai_addrlen);
1761 errmsg(
"could not connect to Ident server at address \"%s\", port %s: %m",
1762 remote_addr_s, ident_port)));
1763 ident_return =
false;
1764 goto ident_inet_done;
1768 snprintf(ident_query,
sizeof(ident_query),
"%s,%s\r\n",
1769 remote_port, local_port);
1776 rc =
send(sock_fd, ident_query, strlen(ident_query), 0);
1777 }
while (rc < 0 && errno ==
EINTR);
1783 errmsg(
"could not send query to Ident server at address \"%s\", port %s: %m",
1784 remote_addr_s, ident_port)));
1785 ident_return =
false;
1786 goto ident_inet_done;
1793 rc =
recv(sock_fd, ident_response,
sizeof(ident_response) - 1, 0);
1794 }
while (rc < 0 && errno ==
EINTR);
1800 errmsg(
"could not receive response from Ident server at address \"%s\", port %s: %m",
1801 remote_addr_s, ident_port)));
1802 ident_return =
false;
1803 goto ident_inet_done;
1806 ident_response[rc] =
'\0';
1810 (
errmsg(
"invalidly formatted response from Ident server: \"%s\"",
1853 struct passwd pwbuf;
1863 if (errno == ENOSYS)
1865 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1866 errmsg(
"peer authentication is not supported on this platform")));
1870 errmsg(
"could not get peer credentials: %m")));
1875 rc = getpwuid_r(uid, &pwbuf,
buf,
sizeof buf, &pw);
1880 errmsg(
"could not look up local user ID %ld: %m", (
long) uid));
1886 errmsg(
"local user with ID %ld does not exist", (
long) uid));
1920pam_passwd_conv_proc(
int num_msg,
const struct pam_message **msg,
1921 struct pam_response **resp,
void *appdata_ptr)
1924 struct pam_response *reply;
1928 passwd = (
char *) appdata_ptr;
1935 passwd = pam_passwd;
1940 if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
1941 return PAM_CONV_ERR;
1947 if ((reply =
calloc(num_msg,
sizeof(
struct pam_response))) == NULL)
1950 (
errcode(ERRCODE_OUT_OF_MEMORY),
1951 errmsg(
"out of memory")));
1952 return PAM_CONV_ERR;
1955 for (
i = 0;
i < num_msg;
i++)
1957 switch (msg[
i]->msg_style)
1959 case PAM_PROMPT_ECHO_OFF:
1960 if (strlen(passwd) == 0)
1976 pam_no_password =
true;
1980 if ((reply[
i].resp = strdup(passwd)) == NULL)
1982 reply[
i].resp_retcode = PAM_SUCCESS;
1986 (
errmsg(
"error from underlying PAM layer: %s",
1991 if ((reply[
i].resp = strdup(
"")) == NULL)
1993 reply[
i].resp_retcode = PAM_SUCCESS;
1997 (
errmsg(
"unsupported PAM conversation %d/\"%s\"",
1999 msg[
i]->msg ? msg[
i]->msg :
"(none)")));
2009 for (
i = 0;
i < num_msg;
i++)
2010 free(reply[
i].resp);
2013 return PAM_CONV_ERR;
2024 pam_handle_t *pamh = NULL;
2032 pam_port_cludge =
port;
2033 pam_no_password =
false;
2044 if (
port->hba->pamservice &&
port->hba->pamservice[0] !=
'\0')
2045 retval = pam_start(
port->hba->pamservice,
"pgsql@",
2046 &pam_passw_conv, &pamh);
2048 retval = pam_start(PGSQL_PAM_SERVICE,
"pgsql@",
2049 &pam_passw_conv, &pamh);
2051 if (retval != PAM_SUCCESS)
2054 (
errmsg(
"could not create PAM authenticator: %s",
2055 pam_strerror(pamh, retval))));
2060 retval = pam_set_item(pamh, PAM_USER,
user);
2062 if (retval != PAM_SUCCESS)
2065 (
errmsg(
"pam_set_item(PAM_USER) failed: %s",
2066 pam_strerror(pamh, retval))));
2073 char hostinfo[NI_MAXHOST];
2076 if (
port->hba->pam_use_hostname)
2079 flags = NI_NUMERICHOST | NI_NUMERICSERV;
2082 hostinfo,
sizeof(hostinfo), NULL, 0,
2092 retval = pam_set_item(pamh, PAM_RHOST, hostinfo);
2094 if (retval != PAM_SUCCESS)
2097 (
errmsg(
"pam_set_item(PAM_RHOST) failed: %s",
2098 pam_strerror(pamh, retval))));
2104 retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
2106 if (retval != PAM_SUCCESS)
2109 (
errmsg(
"pam_set_item(PAM_CONV) failed: %s",
2110 pam_strerror(pamh, retval))));
2115 retval = pam_authenticate(pamh, 0);
2117 if (retval != PAM_SUCCESS)
2120 if (!pam_no_password)
2122 (
errmsg(
"pam_authenticate failed: %s",
2123 pam_strerror(pamh, retval))));
2128 retval = pam_acct_mgmt(pamh, 0);
2130 if (retval != PAM_SUCCESS)
2133 if (!pam_no_password)
2135 (
errmsg(
"pam_acct_mgmt failed: %s",
2136 pam_strerror(pamh, retval))));
2141 retval = pam_end(pamh, retval);
2143 if (retval != PAM_SUCCESS)
2146 (
errmsg(
"could not release PAM authenticator: %s",
2147 pam_strerror(pamh, retval))));
2152 if (retval == PAM_SUCCESS)
2183 retval = auth_userokay(
user, NULL,
"auth-postgresql", passwd);
2202static int errdetail_for_ldap(LDAP *ldap);
2209InitializeLDAPConnection(
Port *
port, LDAP **ldap)
2212 int ldapversion = LDAP_VERSION3;
2215 scheme =
port->hba->ldapscheme;
2219 if (strcmp(scheme,
"ldaps") == 0)
2220 *ldap = ldap_sslinit(
port->hba->ldapserver,
port->hba->ldapport, 1);
2222 *ldap = ldap_init(
port->hba->ldapserver,
port->hba->ldapport);
2226 (
errmsg(
"could not initialize LDAP: error code %d",
2227 (
int) LdapGetLastError())));
2232#ifdef HAVE_LDAP_INITIALIZE
2243 char *hostlist = NULL;
2255 if (!
port->hba->ldapserver ||
port->hba->ldapserver[0] ==
'\0')
2260 if (ldap_dn2domain(
port->hba->ldapbasedn, &domain))
2263 (
errmsg(
"could not extract domain name from ldapbasedn")));
2268 if (ldap_domain2hostlist(domain, &hostlist))
2271 (
errmsg(
"LDAP authentication could not find DNS SRV records for \"%s\"",
2273 (
errhint(
"Set an LDAP server name explicitly."))));
2274 ldap_memfree(domain);
2277 ldap_memfree(domain);
2281 append_port =
false;
2286 p =
port->hba->ldapserver;
2296 size = strcspn(p,
" ");
2317 ldap_memfree(hostlist);
2320 r = ldap_initialize(ldap, uris.
data);
2322 if (r != LDAP_SUCCESS)
2325 (
errmsg(
"could not initialize LDAP: %s",
2326 ldap_err2string(r))));
2332 if (strcmp(scheme,
"ldaps") == 0)
2335 (
errmsg(
"ldaps not supported with this LDAP library")));
2339 *ldap = ldap_init(
port->hba->ldapserver,
port->hba->ldapport);
2343 (
errmsg(
"could not initialize LDAP: %m")));
2350 if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
2353 (
errmsg(
"could not set LDAP protocol version: %s",
2354 ldap_err2string(r)),
2355 errdetail_for_ldap(*ldap)));
2360 if (
port->hba->ldaptls)
2363 if ((r = ldap_start_tls_s(*ldap, NULL, NULL)) != LDAP_SUCCESS)
2365 if ((r = ldap_start_tls_s(*ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS)
2369 (
errmsg(
"could not start LDAP TLS session: %s",
2370 ldap_err2string(r)),
2371 errdetail_for_ldap(*ldap)));
2381#define LPH_USERNAME "$username"
2382#define LPH_USERNAME_LEN (sizeof(LPH_USERNAME) - 1)
2385#ifndef LDAP_NO_ATTRS
2386#define LDAP_NO_ATTRS "1.1"
2391#define LDAPS_PORT 636
2395dummy_ldap_password_mutator(
char *
input)
2405FormatSearchFilter(
const char *pattern,
const char *user_name)
2410 while (*pattern !=
'\0')
2412 if (strncmp(pattern, LPH_USERNAME, LPH_USERNAME_LEN) == 0)
2415 pattern += LPH_USERNAME_LEN;
2434 const char *server_name;
2436#ifdef HAVE_LDAP_INITIALIZE
2442 if ((!
port->hba->ldapserver ||
port->hba->ldapserver[0] ==
'\0') &&
2443 (!
port->hba->ldapbasedn ||
port->hba->ldapbasedn[0] ==
'\0'))
2446 (
errmsg(
"LDAP server not specified, and no ldapbasedn")));
2450 if (!
port->hba->ldapserver ||
port->hba->ldapserver[0] ==
'\0')
2453 (
errmsg(
"LDAP server not specified")));
2462 server_name =
port->hba->ldapserver ?
port->hba->ldapserver :
"";
2464 if (
port->hba->ldapport == 0)
2466 if (
port->hba->ldapscheme != NULL &&
2467 strcmp(
port->hba->ldapscheme,
"ldaps") == 0)
2468 port->hba->ldapport = LDAPS_PORT;
2470 port->hba->ldapport = LDAP_PORT;
2486 if (
port->hba->ldapbasedn)
2493 LDAPMessage *search_message;
2495 char *attributes[] = {LDAP_NO_ATTRS, NULL};
2506 for (
c =
port->user_name; *
c;
c++)
2515 (
errmsg(
"invalid character in user name for LDAP authentication")));
2526 r = ldap_simple_bind_s(ldap,
2527 port->hba->ldapbinddn ?
port->hba->ldapbinddn :
"",
2529 if (r != LDAP_SUCCESS)
2532 (
errmsg(
"could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s",
2533 port->hba->ldapbinddn ?
port->hba->ldapbinddn :
"",
2535 ldap_err2string(r)),
2536 errdetail_for_ldap(ldap)));
2543 if (
port->hba->ldapsearchfilter)
2544 filter = FormatSearchFilter(
port->hba->ldapsearchfilter,
port->user_name);
2545 else if (
port->hba->ldapsearchattribute)
2546 filter =
psprintf(
"(%s=%s)",
port->hba->ldapsearchattribute,
port->user_name);
2550 search_message = NULL;
2551 r = ldap_search_s(ldap,
2552 port->hba->ldapbasedn,
2553 port->hba->ldapscope,
2559 if (r != LDAP_SUCCESS)
2562 (
errmsg(
"could not search LDAP for filter \"%s\" on server \"%s\": %s",
2563 filter, server_name, ldap_err2string(r)),
2564 errdetail_for_ldap(ldap)));
2565 if (search_message != NULL)
2566 ldap_msgfree(search_message);
2573 count = ldap_count_entries(ldap, search_message);
2578 (
errmsg(
"LDAP user \"%s\" does not exist",
port->user_name),
2579 errdetail(
"LDAP search for filter \"%s\" on server \"%s\" returned no entries.",
2580 filter, server_name)));
2583 (
errmsg(
"LDAP user \"%s\" is not unique",
port->user_name),
2584 errdetail_plural(
"LDAP search for filter \"%s\" on server \"%s\" returned %d entry.",
2585 "LDAP search for filter \"%s\" on server \"%s\" returned %d entries.",
2587 filter, server_name, count)));
2592 ldap_msgfree(search_message);
2596 entry = ldap_first_entry(ldap, search_message);
2597 dn = ldap_get_dn(ldap, entry);
2602 (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &
error);
2604 (
errmsg(
"could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
2605 filter, server_name,
2606 ldap_err2string(
error)),
2607 errdetail_for_ldap(ldap)));
2611 ldap_msgfree(search_message);
2618 ldap_msgfree(search_message);
2622 port->hba->ldapprefix ?
port->hba->ldapprefix :
"",
2624 port->hba->ldapsuffix ?
port->hba->ldapsuffix :
"");
2626 r = ldap_simple_bind_s(ldap, fulluser, passwd);
2628 if (r != LDAP_SUCCESS)
2631 (
errmsg(
"LDAP login failed for user \"%s\" on server \"%s\": %s",
2632 fulluser, server_name, ldap_err2string(r)),
2633 errdetail_for_ldap(ldap)));
2655errdetail_for_ldap(LDAP *ldap)
2660 rc = ldap_get_option(ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, &message);
2661 if (rc == LDAP_SUCCESS && message != NULL)
2663 errdetail(
"LDAP diagnostics: %s", message);
2664 ldap_memfree(message);
2682 char *peer_username = NULL;
2687 switch (
port->hba->clientcertname)
2690 peer_username =
port->peer_dn;
2693 peer_username =
port->peer_cn;
2697 if (peer_username == NULL ||
2698 strlen(peer_username) <= 0)
2701 (
errmsg(
"certificate authentication failed for user \"%s\": client certificate contains no user name",
2722 (
errmsg(
"certificate authentication failed for user \"%s\": unable to retrieve subject DN",
2741 switch (
port->hba->clientcertname)
2745 (
errmsg(
"certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch",
2750 (
errmsg(
"certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch",
2755 return status_check_usermap;
2769#define RADIUS_VECTOR_LENGTH 16
2770#define RADIUS_HEADER_LENGTH 20
2771#define RADIUS_MAX_PASSWORD_LENGTH 128
2774#define RADIUS_BUFFER_SIZE 1024
2794#define RADIUS_ACCESS_REQUEST 1
2795#define RADIUS_ACCESS_ACCEPT 2
2796#define RADIUS_ACCESS_REJECT 3
2799#define RADIUS_USER_NAME 1
2800#define RADIUS_PASSWORD 2
2801#define RADIUS_SERVICE_TYPE 6
2802#define RADIUS_NAS_IDENTIFIER 32
2805#define RADIUS_AUTHENTICATE_ONLY 8
2808#define RADIUS_TIMEOUT 3
2824 "adding attribute code %d with length %d to radius packet would create oversize packet, ignoring",
2849 if (
port->hba->radiusservers ==
NIL)
2852 (
errmsg(
"RADIUS server not specified")));
2856 if (
port->hba->radiussecrets ==
NIL)
2859 (
errmsg(
"RADIUS secret not specified")));
2884 foreach(server,
port->hba->radiusservers)
2888 radiusports ?
lfirst(radiusports) : NULL,
2889 identifiers ?
lfirst(identifiers) : NULL,
2919 secrets =
lnext(
port->hba->radiussecrets, secrets);
2921 radiusports =
lnext(
port->hba->radiusports, radiusports);
2923 identifiers =
lnext(
port->hba->radiusidentifiers, identifiers);
2938 void *radius_buffer = &radius_send_pack;
2939 void *receive_buffer = &radius_recv_pack;
2942 int encryptedpasswordlen;
2948 struct sockaddr_in6 localaddr;
2949 struct sockaddr_in6 remoteaddr;
2950 struct addrinfo hint;
2951 struct addrinfo *serveraddrs;
2955 struct timeval endtime;
2963 if (identifier == NULL)
2964 identifier =
"postgresql";
2966 MemSet(&hint, 0,
sizeof(hint));
2967 hint.ai_socktype = SOCK_DGRAM;
2968 hint.ai_family = AF_UNSPEC;
2972 if (r || !serveraddrs)
2975 (
errmsg(
"could not translate RADIUS server name \"%s\" to address: %s",
2989 (
errmsg(
"could not generate random encryption vector")));
3006 memcpy(cryptvector, secret, strlen(secret));
3009 md5trailer = packet->
vector;
3012 const char *errstr = NULL;
3020 md5trailer = encryptedpassword +
i;
3023 encryptedpassword +
i, &errstr))
3026 (
errmsg(
"could not perform MD5 encryption of password: %s",
3035 if (
j < strlen(passwd))
3036 encryptedpassword[
j] = passwd[
j] ^ encryptedpassword[
j];
3038 encryptedpassword[
j] =
'\0' ^ encryptedpassword[
j];
3046 packetlength = packet->
length;
3049 sock =
socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
3053 (
errmsg(
"could not create RADIUS socket: %m")));
3058 memset(&localaddr, 0,
sizeof(localaddr));
3059 localaddr.sin6_family = serveraddrs[0].ai_family;
3060 localaddr.sin6_addr = in6addr_any;
3061 if (localaddr.sin6_family == AF_INET6)
3062 addrsize =
sizeof(
struct sockaddr_in6);
3064 addrsize =
sizeof(
struct sockaddr_in);
3066 if (
bind(sock, (
struct sockaddr *) &localaddr, addrsize))
3069 (
errmsg(
"could not bind local RADIUS socket: %m")));
3075 if (sendto(sock, radius_buffer, packetlength, 0,
3076 serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
3079 (
errmsg(
"could not send RADIUS packet: %m")));
3103 struct timeval timeout;
3106 const char *errstr = NULL;
3109 timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (
now.tv_sec * 1000000 +
now.tv_usec);
3110 if (timeoutval <= 0)
3113 (
errmsg(
"timeout waiting for RADIUS response from %s",
3118 timeout.tv_sec = timeoutval / 1000000;
3119 timeout.tv_usec = timeoutval % 1000000;
3122 FD_SET(sock, &fdset);
3124 r =
select(sock + 1, &fdset, NULL, NULL, &timeout);
3132 (
errmsg(
"could not check status on RADIUS socket: %m")));
3139 (
errmsg(
"timeout waiting for RADIUS response from %s",
3156 addrsize =
sizeof(remoteaddr);
3158 (
struct sockaddr *) &remoteaddr, &addrsize);
3159 if (packetlength < 0)
3162 (
errmsg(
"could not read RADIUS response: %m")));
3170 (
errmsg(
"RADIUS response from %s was sent from incorrect port: %d",
3171 server,
pg_ntoh16(remoteaddr.sin6_port))));
3178 (
errmsg(
"RADIUS response from %s too short: %d", server, packetlength)));
3185 (
errmsg(
"RADIUS response from %s has corrupt length: %d (actual length %d)",
3190 if (packet->
id != receivepacket->
id)
3193 (
errmsg(
"RADIUS response from %s is to a different request: %d (should be %d)",
3194 server, receivepacket->
id, packet->
id)));
3202 cryptvector =
palloc(packetlength + strlen(secret));
3204 memcpy(cryptvector, receivepacket, 4);
3213 memcpy(cryptvector + packetlength, secret, strlen(secret));
3216 packetlength + strlen(secret),
3217 encryptedpassword, &errstr))
3220 (
errmsg(
"could not perform MD5 encryption of received packet: %s",
3230 (
errmsg(
"RADIUS response from %s has incorrect MD5 signature",
3248 (
errmsg(
"RADIUS response from %s has invalid code (%d) for user \"%s\"",
3249 server, receivepacket->
code, user_name)));
const pg_be_sasl_mech pg_be_oauth_mech
int CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, char *shadow_pass, const char **logdetail)
const pg_be_sasl_mech pg_be_scram_mech
static void radius_add_attribute(radius_packet *packet, uint8 type, const unsigned char *data, int len)
void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extralen)
#define RADIUS_HEADER_LENGTH
static int CheckPWChallengeAuth(Port *port, const char **logdetail)
#define RADIUS_AUTHENTICATE_ONLY
static int ident_inet(hbaPort *port)
char * pg_krb_server_keyfile
#define IDENT_USERNAME_MAX
#define RADIUS_ACCESS_REQUEST
bool pg_krb_caseins_users
static char * recv_password_packet(Port *port)
#define RADIUS_NAS_IDENTIFIER
#define RADIUS_SERVICE_TYPE
bool pg_gss_accept_delegation
static int CheckRADIUSAuth(Port *port)
static void auth_failed(Port *port, int status, const char *logdetail)
#define RADIUS_MAX_PASSWORD_LENGTH
ClientAuthentication_hook_type ClientAuthentication_hook
void ClientAuthentication(Port *port)
static int auth_peer(hbaPort *port)
#define RADIUS_ACCESS_REJECT
static int CheckMD5Auth(Port *port, char *shadow_pass, const char **logdetail)
void set_authn_id(Port *port, const char *id)
#define RADIUS_ACCESS_ACCEPT
static int PerformRadiusTransaction(const char *server, const char *secret, const char *portstr, const char *identifier, const char *user_name, const char *passwd)
#define RADIUS_VECTOR_LENGTH
static bool interpret_ident_response(const char *ident_response, char *ident_user)
#define HOSTNAME_LOOKUP_DETAIL(port)
static int CheckPasswordAuth(Port *port, const char **logdetail)
#define RADIUS_BUFFER_SIZE
PGDLLIMPORT auth_password_hook_typ ldap_password_hook
void(* ClientAuthentication_hook_type)(Port *, int)
char *(* auth_password_hook_typ)(char *input)
#define PG_MAX_AUTH_TOKEN_LENGTH
Datum now(PG_FUNCTION_ARGS)
@ LOG_CONNECTION_AUTHENTICATION
void pg_store_delegated_credential(gss_cred_id_t cred)
void pg_GSS_error(const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
bool secure_loaded_verify_locations(void)
#define unconstify(underlying_type, expr)
#define FLEXIBLE_ARRAY_MEMBER
#define MemSet(start, val, len)
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const char **logdetail)
char * get_role_password(const char *role, const char **logdetail)
PasswordType get_password_type(const char *shadow_pass)
int md5_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const char *md5_salt, int md5_salt_len, const char **logdetail)
int errcode_for_socket_access(void)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
int errdetail_log(const char *fmt,...)
#define ereport(elevel,...)
#define ERRCODE_INVALID_PASSWORD
Assert(PointerIsAligned(start, uint64))
bool pg_isblank(const char c)
void hba_getauthmethod(hbaPort *port)
int check_usermap(const char *usermap_name, const char *pg_user, const char *system_user, bool case_insensitive)
const char * hba_authname(UserAuth auth_method)
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
char * MemoryContextStrdup(MemoryContext context, const char *string)
void * MemoryContextAllocZero(MemoryContext context, Size size)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
bool pg_md5_binary(const void *buff, size_t len, void *outbuf, const char **errstr)
#define CHECK_FOR_INTERRUPTS()
ClientConnectionInfo MyClientConnectionInfo
static int list_length(const List *l)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
bool pg_strong_random(void *buf, size_t len)
int pg_strcasecmp(const char *s1, const char *s2)
int getpeereid(int sock, uid_t *uid, gid_t *gid)
int pq_getmessage(StringInfo s, int maxlen)
void pq_startmsgread(void)
#define PqMsg_GSSResponse
#define PqMsg_AuthenticationRequest
#define AUTH_REQ_PASSWORD
#define AUTH_REQ_GSS_CONT
#define PqMsg_PasswordMessage
#define AUTH_REQ_SASL_FIN
char * psprintf(const char *fmt,...)
const char * gai_strerror(int ecode)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
struct sockaddr_storage addr
uint8 data[FLEXIBLE_ARRAY_MEMBER]
uint8 vector[RADIUS_VECTOR_LENGTH]
#define bind(s, addr, addrlen)
#define recv(s, buf, len, flags)
#define send(s, buf, len, flags)
#define socket(af, type, protocol)
#define connect(s, name, namelen)
#define select(n, r, w, e, timeout)
int gettimeofday(struct timeval *tp, void *tzp)