23 #ifdef HAVE_SYS_SELECT_H
24 #include <sys/select.h>
62 const char **logdetail);
70 #define IDENT_USERNAME_MAX 512
73 #define IDENT_PORT 113
90 #ifdef HAVE_PAM_PAM_APPL_H
91 #include <pam/pam_appl.h>
93 #ifdef HAVE_SECURITY_PAM_APPL_H
94 #include <security/pam_appl.h>
97 #define PGSQL_PAM_SERVICE "postgresql"
100 static int pam_passwd_conv_proc(
int num_msg,
const struct pam_message **msg,
101 struct pam_response **resp,
void *appdata_ptr);
103 static struct pam_conv pam_passw_conv = {
104 &pam_passwd_conv_proc,
108 static const char *pam_passwd = NULL;
110 static Port *pam_port_cludge;
112 static bool pam_no_password;
121 #include <bsd_auth.h>
134 #define LDAP_DEPRECATED 1
141 ULONG (*__ldap_start_tls_sA) (IN PLDAP ExternalHandle,
142 OUT PULONG ServerReturnValue,
143 OUT LDAPMessage **result,
144 IN PLDAPControlA * ServerControls,
145 IN PLDAPControlA * ClientControls
149 static int CheckLDAPAuth(
Port *
port);
152 #ifndef LDAP_OPT_DIAGNOSTIC_MESSAGE
153 #define LDAP_OPT_DIAGNOSTIC_MESSAGE LDAP_OPT_ERROR_STRING
163 static int CheckCertAuth(
Port *
port);
182 static int pg_GSS_checkauth(
Port *
port);
183 static int pg_GSS_recvauth(
Port *
port);
192 typedef SECURITY_STATUS
193 (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) (PCtxtHandle,
void **);
194 static int pg_SSPI_recvauth(
Port *
port);
195 static int pg_SSPI_make_upn(
char *accountname,
196 size_t accountnamesize,
198 size_t domainnamesize,
199 bool update_accountname);
207 static int PerformRadiusTransaction(
const char *server,
const char *secret,
const char *portstr,
const char *identifier,
const char *user_name,
const char *passwd);
224 #define PG_MAX_AUTH_TOKEN_LENGTH 65535
256 int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
271 switch (
port->hba->auth_method)
275 errstr =
gettext_noop(
"authentication failed for user \"%s\": host rejected");
278 errstr =
gettext_noop(
"\"trust\" authentication failed for user \"%s\"");
281 errstr =
gettext_noop(
"Ident authentication failed for user \"%s\"");
284 errstr =
gettext_noop(
"Peer authentication failed for user \"%s\"");
289 errstr =
gettext_noop(
"password authentication failed for user \"%s\"");
294 errstr =
gettext_noop(
"GSSAPI authentication failed for user \"%s\"");
297 errstr =
gettext_noop(
"SSPI authentication failed for user \"%s\"");
300 errstr =
gettext_noop(
"PAM authentication failed for user \"%s\"");
303 errstr =
gettext_noop(
"BSD authentication failed for user \"%s\"");
306 errstr =
gettext_noop(
"LDAP authentication failed for user \"%s\"");
309 errstr =
gettext_noop(
"certificate authentication failed for user \"%s\"");
312 errstr =
gettext_noop(
"RADIUS authentication failed for user \"%s\"");
315 errstr =
gettext_noop(
"authentication failed for user \"%s\": invalid authentication method");
319 cdetail =
psprintf(
_(
"Connection matched pg_hba.conf line %d: \"%s\""),
320 port->hba->linenumber,
port->hba->rawline);
322 logdetail =
psprintf(
"%s\n%s", logdetail, cdetail);
362 (
errmsg(
"authentication identifier set more than once"),
363 errdetail_log(
"previous identifier: \"%s\"; new identifier: \"%s\"",
364 port->authn_id,
id)));
372 errmsg(
"connection authenticated: identity=\"%s\" method=%s "
375 port->hba->linenumber));
388 const char *logdetail = NULL;
410 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
411 errmsg(
"client certificates can only be checked if a root certificate store is available")));
419 if (!
port->peer_cert_valid)
421 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
422 errmsg(
"connection requires a valid client certificate")));
428 switch (
port->hba->auth_method)
444 const char *encryption_state;
447 hostinfo,
sizeof(hostinfo),
453 (
port->gss &&
port->gss->enc) ?
_(
"GSS encryption") :
456 port->ssl_in_use ?
_(
"SSL encryption") :
462 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
464 errmsg(
"pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
465 hostinfo,
port->user_name,
469 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
471 errmsg(
"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
472 hostinfo,
port->user_name,
490 const char *encryption_state;
493 hostinfo,
sizeof(hostinfo),
499 (
port->gss &&
port->gss->enc) ?
_(
"GSS encryption") :
502 port->ssl_in_use ?
_(
"SSL encryption") :
506 #define HOSTNAME_LOOKUP_DETAIL(port) \
507 (port->remote_hostname ? \
508 (port->remote_hostname_resolv == +1 ? \
509 errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
510 port->remote_hostname) : \
511 port->remote_hostname_resolv == 0 ? \
512 errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
513 port->remote_hostname) : \
514 port->remote_hostname_resolv == -1 ? \
515 errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
516 port->remote_hostname) : \
517 port->remote_hostname_resolv == -2 ? \
518 errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
519 port->remote_hostname, \
520 gai_strerror(port->remote_hostname_errcode)) : \
522 : (port->remote_hostname_resolv == -2 ? \
523 errdetail_log("Could not resolve client IP address to a host name: %s.", \
524 gai_strerror(port->remote_hostname_errcode)) : \
529 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
531 errmsg(
"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
532 hostinfo,
port->user_name,
537 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
539 errmsg(
"no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
540 hostinfo,
port->user_name,
550 if (
port->gss == NULL)
551 port->gss = (pg_gssinfo *)
554 port->gss->auth =
true;
574 if (
port->gss == NULL)
575 port->gss = (pg_gssinfo *)
711 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
712 errmsg(
"expected password response, got message type %d",
730 if (strlen(
buf.data) + 1 !=
buf.len)
732 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
733 errmsg(
"invalid password packet size")));
751 errmsg(
"empty password returned by client")));
879 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
880 errmsg(
"MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
886 (
errmsg(
"could not generate random MD5 salt")));
898 md5Salt, 4, logdetail);
922 gss_buffer_desc gbuf;
934 (
errcode(ERRCODE_OUT_OF_MEMORY),
935 errmsg(
"could not set environment: %m")));
945 port->gss->cred = GSS_C_NO_CREDENTIAL;
950 port->gss->ctx = GSS_C_NO_CONTEXT;
970 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
971 errmsg(
"expected GSS response, got message type %d",
986 gbuf.length =
buf.len;
987 gbuf.value =
buf.data;
989 elog(
DEBUG4,
"processing received GSS token of length %u",
990 (
unsigned int) gbuf.length);
992 maj_stat = gss_accept_sec_context(&min_stat,
996 GSS_C_NO_CHANNEL_BINDINGS,
1007 elog(
DEBUG5,
"gss_accept_sec_context major: %u, "
1008 "minor: %u, outlen: %u, outflags: %x",
1010 (
unsigned int)
port->gss->outbuf.length, gflags);
1014 if (
port->gss->outbuf.length != 0)
1019 elog(
DEBUG4,
"sending GSS response token of length %u",
1020 (
unsigned int)
port->gss->outbuf.length);
1023 port->gss->outbuf.value,
port->gss->outbuf.length);
1025 gss_release_buffer(&lmin_s, &
port->gss->outbuf);
1028 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
1030 gss_delete_sec_context(&lmin_s, &
port->gss->ctx, GSS_C_NO_BUFFER);
1032 maj_stat, min_stat);
1036 if (maj_stat == GSS_S_CONTINUE_NEEDED)
1039 }
while (maj_stat == GSS_S_CONTINUE_NEEDED);
1041 if (
port->gss->cred != GSS_C_NO_CREDENTIAL)
1046 gss_release_cred(&min_stat, &
port->gss->cred);
1048 return pg_GSS_checkauth(
port);
1062 gss_buffer_desc gbuf;
1069 maj_stat = gss_display_name(&min_stat,
port->gss->name, &gbuf, NULL);
1070 if (maj_stat != GSS_S_COMPLETE)
1073 maj_stat, min_stat);
1081 princ =
palloc(gbuf.length + 1);
1082 memcpy(princ, gbuf.value, gbuf.length);
1083 princ[gbuf.length] =
'\0';
1084 gss_release_buffer(&lmin_s, &gbuf);
1100 if (strchr(princ,
'@'))
1102 char *cp = strchr(princ,
'@');
1109 if (!
port->hba->include_realm)
1113 if (
port->hba->krb_realm != NULL && strlen(
port->hba->krb_realm))
1121 ret = strcmp(
port->hba->krb_realm, cp);
1127 "GSSAPI realm (%s) and configured realm (%s) don't match",
1128 cp,
port->hba->krb_realm);
1134 else if (
port->hba->krb_realm && strlen(
port->hba->krb_realm))
1137 "GSSAPI did not return realm but realm matching was requested");
1163 pg_SSPI_error(
int severity,
const char *
errmsg, SECURITY_STATUS r)
1167 if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
1168 FORMAT_MESSAGE_FROM_SYSTEM,
1170 sysmsg,
sizeof(sysmsg), NULL) == 0)
1186 CredHandle sspicred;
1187 CtxtHandle *sspictx = NULL,
1191 SecBufferDesc inbuf;
1192 SecBufferDesc outbuf;
1193 SecBuffer OutBuffers[1];
1194 SecBuffer InBuffers[1];
1196 TOKEN_USER *tokenuser;
1200 DWORD accountnamesize =
sizeof(accountname);
1201 DWORD domainnamesize =
sizeof(domainname);
1202 SID_NAME_USE accountnameuse;
1206 QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
1211 r = AcquireCredentialsHandle(NULL,
1213 SECPKG_CRED_INBOUND,
1221 pg_SSPI_error(
ERROR,
_(
"could not acquire SSPI credentials"), r);
1235 if (sspictx != NULL)
1237 DeleteSecurityContext(sspictx);
1240 FreeCredentialsHandle(&sspicred);
1245 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
1246 errmsg(
"expected SSPI response, got message type %d",
1257 if (sspictx != NULL)
1259 DeleteSecurityContext(sspictx);
1262 FreeCredentialsHandle(&sspicred);
1267 inbuf.ulVersion = SECBUFFER_VERSION;
1269 inbuf.pBuffers = InBuffers;
1270 InBuffers[0].pvBuffer =
buf.data;
1271 InBuffers[0].cbBuffer =
buf.len;
1272 InBuffers[0].BufferType = SECBUFFER_TOKEN;
1275 OutBuffers[0].pvBuffer = NULL;
1276 OutBuffers[0].BufferType = SECBUFFER_TOKEN;
1277 OutBuffers[0].cbBuffer = 0;
1278 outbuf.cBuffers = 1;
1279 outbuf.pBuffers = OutBuffers;
1280 outbuf.ulVersion = SECBUFFER_VERSION;
1282 elog(
DEBUG4,
"processing received SSPI token of length %u",
1283 (
unsigned int)
buf.len);
1285 r = AcceptSecurityContext(&sspicred,
1288 ASC_REQ_ALLOCATE_MEMORY,
1289 SECURITY_NETWORK_DREP,
1298 if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
1303 elog(
DEBUG4,
"sending SSPI response token of length %u",
1304 (
unsigned int) outbuf.pBuffers[0].cbBuffer);
1306 port->gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
1307 port->gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;
1310 port->gss->outbuf.value,
port->gss->outbuf.length);
1312 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
1315 if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
1317 if (sspictx != NULL)
1319 DeleteSecurityContext(sspictx);
1322 FreeCredentialsHandle(&sspicred);
1323 pg_SSPI_error(
ERROR,
1324 _(
"could not accept SSPI security context"), r);
1333 if (sspictx == NULL)
1335 sspictx =
malloc(
sizeof(CtxtHandle));
1336 if (sspictx == NULL)
1338 (
errmsg(
"out of memory")));
1341 memcpy(sspictx, &newctx,
sizeof(CtxtHandle));
1343 if (r == SEC_I_CONTINUE_NEEDED)
1346 }
while (r == SEC_I_CONTINUE_NEEDED);
1352 FreeCredentialsHandle(&sspicred);
1365 secur32 = LoadLibrary(
"SECUR32.DLL");
1366 if (secur32 == NULL)
1368 (
errmsg(
"could not load library \"%s\": error code %lu",
1369 "SECUR32.DLL", GetLastError())));
1371 _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN) (
pg_funcptr_t)
1372 GetProcAddress(secur32,
"QuerySecurityContextToken");
1373 if (_QuerySecurityContextToken == NULL)
1375 FreeLibrary(secur32);
1377 (
errmsg_internal(
"could not locate QuerySecurityContextToken in secur32.dll: error code %lu",
1381 r = (_QuerySecurityContextToken) (sspictx, &token);
1384 FreeLibrary(secur32);
1385 pg_SSPI_error(
ERROR,
1386 _(
"could not get token from SSPI security context"), r);
1389 FreeLibrary(secur32);
1395 DeleteSecurityContext(sspictx);
1398 if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
1400 (
errmsg_internal(
"could not get token information buffer size: error code %lu",
1403 tokenuser =
malloc(retlen);
1404 if (tokenuser == NULL)
1406 (
errmsg(
"out of memory")));
1408 if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
1415 if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
1416 domainname, &domainnamesize, &accountnameuse))
1423 if (!
port->hba->compat_realm)
1425 int status = pg_SSPI_make_upn(accountname,
sizeof(accountname),
1426 domainname,
sizeof(domainname),
1427 port->hba->upn_username);
1440 if (
port->hba->compat_realm)
1443 authn_id =
psprintf(
"%s\\%s", domainname, accountname);
1448 authn_id =
psprintf(
"%s@%s", accountname, domainname);
1458 if (
port->hba->krb_realm && strlen(
port->hba->krb_realm))
1463 "SSPI domain (%s) and configured domain (%s) don't match",
1464 domainname,
port->hba->krb_realm);
1476 if (
port->hba->include_realm)
1481 namebuf =
psprintf(
"%s@%s", accountname, domainname);
1495 pg_SSPI_make_upn(
char *accountname,
1496 size_t accountnamesize,
1498 size_t domainnamesize,
1499 bool update_accountname)
1502 char *upname = NULL;
1504 ULONG upnamesize = 0;
1505 size_t upnamerealmsize;
1515 samname =
psprintf(
"%s\\%s", domainname, accountname);
1516 res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
1519 if ((!
res && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1524 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1525 errmsg(
"could not translate name")));
1530 upname =
palloc(upnamesize);
1532 res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
1533 upname, &upnamesize);
1537 p = strchr(upname,
'@');
1539 if (!
res || p == NULL)
1543 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1544 errmsg(
"could not translate name")));
1549 upnamerealmsize = upnamesize - (p - upname + 1);
1552 if (upnamerealmsize > domainnamesize)
1556 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1557 errmsg(
"realm name too long")));
1562 strcpy(domainname, p + 1);
1565 if (update_accountname)
1567 if ((p - upname + 1) > accountnamesize)
1571 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1572 errmsg(
"translated account name too long")));
1577 strcpy(accountname, upname);
1602 const char *
cursor = ident_response;
1607 if (strlen(ident_response) < 2)
1609 else if (ident_response[strlen(ident_response) - 2] !=
'\r')
1621 char response_type[80];
1629 i < (
int) (
sizeof(response_type) - 1))
1630 response_type[
i++] = *
cursor++;
1631 response_type[
i] =
'\0';
1634 if (strcmp(response_type,
"USERID") != 0)
1663 ident_user[
i] =
'\0';
1695 char ident_query[80];
1697 struct addrinfo *ident_serv = NULL,
1706 remote_addr_s,
sizeof(remote_addr_s),
1707 remote_port,
sizeof(remote_port),
1710 local_addr_s,
sizeof(local_addr_s),
1711 local_port,
sizeof(local_port),
1716 hints.ai_family = remote_addr.
addr.ss_family;
1717 hints.ai_socktype = SOCK_STREAM;
1718 hints.ai_protocol = 0;
1719 hints.ai_addrlen = 0;
1720 hints.ai_canonname = NULL;
1721 hints.ai_addr = NULL;
1722 hints.ai_next = NULL;
1724 if (rc || !ident_serv)
1727 ident_return =
false;
1728 goto ident_inet_done;
1732 hints.ai_family = local_addr.
addr.ss_family;
1733 hints.ai_socktype = SOCK_STREAM;
1734 hints.ai_protocol = 0;
1735 hints.ai_addrlen = 0;
1736 hints.ai_canonname = NULL;
1737 hints.ai_addr = NULL;
1738 hints.ai_next = NULL;
1743 ident_return =
false;
1744 goto ident_inet_done;
1753 errmsg(
"could not create socket for Ident connection: %m")));
1754 ident_return =
false;
1755 goto ident_inet_done;
1763 rc =
bind(sock_fd, la->ai_addr, la->ai_addrlen);
1768 errmsg(
"could not bind to local address \"%s\": %m",
1770 ident_return =
false;
1771 goto ident_inet_done;
1780 errmsg(
"could not connect to Ident server at address \"%s\", port %s: %m",
1781 remote_addr_s, ident_port)));
1782 ident_return =
false;
1783 goto ident_inet_done;
1787 snprintf(ident_query,
sizeof(ident_query),
"%s,%s\r\n",
1788 remote_port, local_port);
1795 rc =
send(sock_fd, ident_query, strlen(ident_query), 0);
1796 }
while (rc < 0 && errno ==
EINTR);
1802 errmsg(
"could not send query to Ident server at address \"%s\", port %s: %m",
1803 remote_addr_s, ident_port)));
1804 ident_return =
false;
1805 goto ident_inet_done;
1812 rc =
recv(sock_fd, ident_response,
sizeof(ident_response) - 1, 0);
1813 }
while (rc < 0 && errno ==
EINTR);
1819 errmsg(
"could not receive response from Ident server at address \"%s\", port %s: %m",
1820 remote_addr_s, ident_port)));
1821 ident_return =
false;
1822 goto ident_inet_done;
1825 ident_response[rc] =
'\0';
1829 (
errmsg(
"invalidly formatted response from Ident server: \"%s\"",
1879 if (errno == ENOSYS)
1881 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1882 errmsg(
"peer authentication is not supported on this platform")));
1886 errmsg(
"could not get peer credentials: %m")));
1895 int save_errno = errno;
1898 (
errmsg(
"could not look up local user ID %ld: %s",
1900 save_errno ?
strerror(save_errno) :
_(
"user does not exist"))));
1933 pam_passwd_conv_proc(
int num_msg,
const struct pam_message **msg,
1934 struct pam_response **resp,
void *appdata_ptr)
1937 struct pam_response *reply;
1941 passwd = (
char *) appdata_ptr;
1948 passwd = pam_passwd;
1953 if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
1954 return PAM_CONV_ERR;
1960 if ((reply =
calloc(num_msg,
sizeof(
struct pam_response))) == NULL)
1963 (
errcode(ERRCODE_OUT_OF_MEMORY),
1964 errmsg(
"out of memory")));
1965 return PAM_CONV_ERR;
1968 for (
i = 0;
i < num_msg;
i++)
1970 switch (msg[
i]->msg_style)
1972 case PAM_PROMPT_ECHO_OFF:
1973 if (strlen(passwd) == 0)
1989 pam_no_password =
true;
1993 if ((reply[
i].resp = strdup(passwd)) == NULL)
1995 reply[
i].resp_retcode = PAM_SUCCESS;
1999 (
errmsg(
"error from underlying PAM layer: %s",
2004 if ((reply[
i].resp = strdup(
"")) == NULL)
2006 reply[
i].resp_retcode = PAM_SUCCESS;
2010 (
errmsg(
"unsupported PAM conversation %d/\"%s\"",
2012 msg[
i]->msg ? msg[
i]->msg :
"(none)")));
2022 for (
i = 0;
i < num_msg;
i++)
2024 if (reply[
i].resp != NULL)
2025 free(reply[
i].resp);
2029 return PAM_CONV_ERR;
2040 pam_handle_t *pamh = NULL;
2048 pam_port_cludge =
port;
2049 pam_no_password =
false;
2060 if (
port->hba->pamservice &&
port->hba->pamservice[0] !=
'\0')
2061 retval = pam_start(
port->hba->pamservice,
"pgsql@",
2062 &pam_passw_conv, &pamh);
2064 retval = pam_start(PGSQL_PAM_SERVICE,
"pgsql@",
2065 &pam_passw_conv, &pamh);
2067 if (retval != PAM_SUCCESS)
2070 (
errmsg(
"could not create PAM authenticator: %s",
2071 pam_strerror(pamh, retval))));
2076 retval = pam_set_item(pamh, PAM_USER,
user);
2078 if (retval != PAM_SUCCESS)
2081 (
errmsg(
"pam_set_item(PAM_USER) failed: %s",
2082 pam_strerror(pamh, retval))));
2092 if (
port->hba->pam_use_hostname)
2098 hostinfo,
sizeof(hostinfo), NULL, 0,
2108 retval = pam_set_item(pamh, PAM_RHOST, hostinfo);
2110 if (retval != PAM_SUCCESS)
2113 (
errmsg(
"pam_set_item(PAM_RHOST) failed: %s",
2114 pam_strerror(pamh, retval))));
2120 retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
2122 if (retval != PAM_SUCCESS)
2125 (
errmsg(
"pam_set_item(PAM_CONV) failed: %s",
2126 pam_strerror(pamh, retval))));
2131 retval = pam_authenticate(pamh, 0);
2133 if (retval != PAM_SUCCESS)
2136 if (!pam_no_password)
2138 (
errmsg(
"pam_authenticate failed: %s",
2139 pam_strerror(pamh, retval))));
2144 retval = pam_acct_mgmt(pamh, 0);
2146 if (retval != PAM_SUCCESS)
2149 if (!pam_no_password)
2151 (
errmsg(
"pam_acct_mgmt failed: %s",
2152 pam_strerror(pamh, retval))));
2157 retval = pam_end(pamh, retval);
2159 if (retval != PAM_SUCCESS)
2162 (
errmsg(
"could not release PAM authenticator: %s",
2163 pam_strerror(pamh, retval))));
2168 if (retval == PAM_SUCCESS)
2199 retval = auth_userokay(
user, NULL,
"auth-postgresql", passwd);
2218 static int errdetail_for_ldap(LDAP *ldap);
2225 InitializeLDAPConnection(
Port *
port, LDAP **ldap)
2228 int ldapversion = LDAP_VERSION3;
2231 scheme =
port->hba->ldapscheme;
2235 if (strcmp(scheme,
"ldaps") == 0)
2236 *ldap = ldap_sslinit(
port->hba->ldapserver,
port->hba->ldapport, 1);
2238 *ldap = ldap_init(
port->hba->ldapserver,
port->hba->ldapport);
2242 (
errmsg(
"could not initialize LDAP: error code %d",
2243 (
int) LdapGetLastError())));
2248 #ifdef HAVE_LDAP_INITIALIZE
2259 char *hostlist = NULL;
2271 if (!
port->hba->ldapserver ||
port->hba->ldapserver[0] ==
'\0')
2276 if (ldap_dn2domain(
port->hba->ldapbasedn, &domain))
2279 (
errmsg(
"could not extract domain name from ldapbasedn")));
2284 if (ldap_domain2hostlist(domain, &hostlist))
2287 (
errmsg(
"LDAP authentication could not find DNS SRV records for \"%s\"",
2289 (
errhint(
"Set an LDAP server name explicitly."))));
2290 ldap_memfree(domain);
2293 ldap_memfree(domain);
2297 append_port =
false;
2302 p =
port->hba->ldapserver;
2312 size = strcspn(p,
" ");
2333 ldap_memfree(hostlist);
2336 r = ldap_initialize(ldap, uris.
data);
2338 if (r != LDAP_SUCCESS)
2341 (
errmsg(
"could not initialize LDAP: %s",
2342 ldap_err2string(r))));
2348 if (strcmp(scheme,
"ldaps") == 0)
2351 (
errmsg(
"ldaps not supported with this LDAP library")));
2355 *ldap = ldap_init(
port->hba->ldapserver,
port->hba->ldapport);
2359 (
errmsg(
"could not initialize LDAP: %m")));
2366 if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
2369 (
errmsg(
"could not set LDAP protocol version: %s",
2370 ldap_err2string(r)),
2371 errdetail_for_ldap(*ldap)));
2376 if (
port->hba->ldaptls)
2379 if ((r = ldap_start_tls_s(*ldap, NULL, NULL)) != LDAP_SUCCESS)
2381 static __ldap_start_tls_sA _ldap_start_tls_sA = NULL;
2383 if (_ldap_start_tls_sA == NULL)
2392 ldaphandle = LoadLibrary(
"WLDAP32.DLL");
2393 if (ldaphandle == NULL)
2400 (
errmsg(
"could not load library \"%s\": error code %lu",
2401 "WLDAP32.DLL", GetLastError())));
2405 _ldap_start_tls_sA = (__ldap_start_tls_sA) (
pg_funcptr_t) GetProcAddress(ldaphandle,
"ldap_start_tls_sA");
2406 if (_ldap_start_tls_sA == NULL)
2409 (
errmsg(
"could not load function _ldap_start_tls_sA in wldap32.dll"),
2410 errdetail(
"LDAP over SSL is not supported on this platform.")));
2412 FreeLibrary(ldaphandle);
2422 if ((r = _ldap_start_tls_sA(*ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS)
2426 (
errmsg(
"could not start LDAP TLS session: %s",
2427 ldap_err2string(r)),
2428 errdetail_for_ldap(*ldap)));
2438 #define LPH_USERNAME "$username"
2439 #define LPH_USERNAME_LEN (sizeof(LPH_USERNAME) - 1)
2442 #ifndef LDAP_NO_ATTRS
2443 #define LDAP_NO_ATTRS "1.1"
2448 #define LDAPS_PORT 636
2456 FormatSearchFilter(
const char *pattern,
const char *user_name)
2461 while (*pattern !=
'\0')
2463 if (strncmp(pattern, LPH_USERNAME, LPH_USERNAME_LEN) == 0)
2466 pattern += LPH_USERNAME_LEN;
2485 const char *server_name;
2487 #ifdef HAVE_LDAP_INITIALIZE
2493 if ((!
port->hba->ldapserver ||
port->hba->ldapserver[0] ==
'\0') &&
2494 (!
port->hba->ldapbasedn ||
port->hba->ldapbasedn[0] ==
'\0'))
2497 (
errmsg(
"LDAP server not specified, and no ldapbasedn")));
2501 if (!
port->hba->ldapserver ||
port->hba->ldapserver[0] ==
'\0')
2504 (
errmsg(
"LDAP server not specified")));
2513 server_name =
port->hba->ldapserver ?
port->hba->ldapserver :
"";
2515 if (
port->hba->ldapport == 0)
2517 if (
port->hba->ldapscheme != NULL &&
2518 strcmp(
port->hba->ldapscheme,
"ldaps") == 0)
2519 port->hba->ldapport = LDAPS_PORT;
2521 port->hba->ldapport = LDAP_PORT;
2537 if (
port->hba->ldapbasedn)
2544 LDAPMessage *search_message;
2546 char *attributes[] = {LDAP_NO_ATTRS, NULL};
2557 for (
c =
port->user_name; *
c;
c++)
2566 (
errmsg(
"invalid character in user name for LDAP authentication")));
2577 r = ldap_simple_bind_s(ldap,
2578 port->hba->ldapbinddn ?
port->hba->ldapbinddn :
"",
2579 port->hba->ldapbindpasswd ?
port->hba->ldapbindpasswd :
"");
2580 if (r != LDAP_SUCCESS)
2583 (
errmsg(
"could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s",
2584 port->hba->ldapbinddn ?
port->hba->ldapbinddn :
"",
2586 ldap_err2string(r)),
2587 errdetail_for_ldap(ldap)));
2594 if (
port->hba->ldapsearchfilter)
2595 filter = FormatSearchFilter(
port->hba->ldapsearchfilter,
port->user_name);
2596 else if (
port->hba->ldapsearchattribute)
2597 filter =
psprintf(
"(%s=%s)",
port->hba->ldapsearchattribute,
port->user_name);
2601 r = ldap_search_s(ldap,
2602 port->hba->ldapbasedn,
2603 port->hba->ldapscope,
2609 if (r != LDAP_SUCCESS)
2612 (
errmsg(
"could not search LDAP for filter \"%s\" on server \"%s\": %s",
2613 filter, server_name, ldap_err2string(r)),
2614 errdetail_for_ldap(ldap)));
2621 count = ldap_count_entries(ldap, search_message);
2626 (
errmsg(
"LDAP user \"%s\" does not exist",
port->user_name),
2627 errdetail(
"LDAP search for filter \"%s\" on server \"%s\" returned no entries.",
2628 filter, server_name)));
2631 (
errmsg(
"LDAP user \"%s\" is not unique",
port->user_name),
2632 errdetail_plural(
"LDAP search for filter \"%s\" on server \"%s\" returned %d entry.",
2633 "LDAP search for filter \"%s\" on server \"%s\" returned %d entries.",
2635 filter, server_name, count)));
2640 ldap_msgfree(search_message);
2644 entry = ldap_first_entry(ldap, search_message);
2645 dn = ldap_get_dn(ldap, entry);
2650 (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &
error);
2652 (
errmsg(
"could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
2653 filter, server_name,
2654 ldap_err2string(
error)),
2655 errdetail_for_ldap(ldap)));
2659 ldap_msgfree(search_message);
2666 ldap_msgfree(search_message);
2669 r = ldap_unbind_s(ldap);
2670 if (r != LDAP_SUCCESS)
2673 (
errmsg(
"could not unbind after searching for user \"%s\" on server \"%s\"",
2674 fulluser, server_name)));
2695 port->hba->ldapprefix ?
port->hba->ldapprefix :
"",
2697 port->hba->ldapsuffix ?
port->hba->ldapsuffix :
"");
2699 r = ldap_simple_bind_s(ldap, fulluser, passwd);
2701 if (r != LDAP_SUCCESS)
2704 (
errmsg(
"LDAP login failed for user \"%s\" on server \"%s\": %s",
2705 fulluser, server_name, ldap_err2string(r)),
2706 errdetail_for_ldap(ldap)));
2728 errdetail_for_ldap(LDAP *ldap)
2733 rc = ldap_get_option(ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, &message);
2734 if (rc == LDAP_SUCCESS && message != NULL)
2736 errdetail(
"LDAP diagnostics: %s", message);
2737 ldap_memfree(message);
2755 char *peer_username = NULL;
2760 switch (
port->hba->clientcertname)
2763 peer_username =
port->peer_dn;
2766 peer_username =
port->peer_cn;
2770 if (peer_username == NULL ||
2771 strlen(peer_username) <= 0)
2774 (
errmsg(
"certificate authentication failed for user \"%s\": client certificate contains no user name",
2795 (
errmsg(
"certificate authentication failed for user \"%s\": unable to retrieve subject DN",
2814 switch (
port->hba->clientcertname)
2818 (
errmsg(
"certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch",
2823 (
errmsg(
"certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch",
2828 return status_check_usermap;
2842 #define RADIUS_VECTOR_LENGTH 16
2843 #define RADIUS_HEADER_LENGTH 20
2844 #define RADIUS_MAX_PASSWORD_LENGTH 128
2847 #define RADIUS_BUFFER_SIZE 1024
2867 #define RADIUS_ACCESS_REQUEST 1
2868 #define RADIUS_ACCESS_ACCEPT 2
2869 #define RADIUS_ACCESS_REJECT 3
2872 #define RADIUS_USER_NAME 1
2873 #define RADIUS_PASSWORD 2
2874 #define RADIUS_SERVICE_TYPE 6
2875 #define RADIUS_NAS_IDENTIFIER 32
2878 #define RADIUS_AUTHENTICATE_ONLY 8
2881 #define RADIUS_TIMEOUT 3
2897 "adding attribute code %d with length %d to radius packet would create oversize packet, ignoring",
2925 (
errmsg(
"RADIUS server not specified")));
2932 (
errmsg(
"RADIUS secret not specified")));
2957 foreach(server,
port->hba->radiusservers)
2961 radiusports ?
lfirst(radiusports) : NULL,
2962 identifiers ?
lfirst(identifiers) : NULL,
2992 secrets =
lnext(
port->hba->radiussecrets, secrets);
2994 radiusports =
lnext(
port->hba->radiusports, radiusports);
2996 identifiers =
lnext(
port->hba->radiusidentifiers, identifiers);
3005 PerformRadiusTransaction(
const char *server,
const char *secret,
const char *portstr,
const char *identifier,
const char *user_name,
const char *passwd)
3011 char *radius_buffer = (
char *) &radius_send_pack;
3012 char *receive_buffer = (
char *) &radius_recv_pack;
3015 int encryptedpasswordlen;
3022 struct sockaddr_in6 localaddr;
3023 struct sockaddr_in6 remoteaddr;
3025 struct sockaddr_in localaddr;
3026 struct sockaddr_in remoteaddr;
3033 struct timeval endtime;
3039 if (portstr == NULL)
3041 if (identifier == NULL)
3042 identifier =
"postgresql";
3044 MemSet(&hint, 0,
sizeof(hint));
3047 port = atoi(portstr);
3050 if (r || !serveraddrs)
3053 (
errmsg(
"could not translate RADIUS server name \"%s\" to address: %s",
3067 (
errmsg(
"could not generate random encryption vector")));
3084 memcpy(cryptvector, secret, strlen(secret));
3087 md5trailer = packet->
vector;
3090 const char *errstr = NULL;
3098 md5trailer = encryptedpassword +
i;
3101 encryptedpassword +
i, &errstr))
3104 (
errmsg(
"could not perform MD5 encryption of password: %s",
3113 if (
j < strlen(passwd))
3114 encryptedpassword[
j] = passwd[
j] ^ encryptedpassword[
j];
3116 encryptedpassword[
j] =
'\0' ^ encryptedpassword[
j];
3124 packetlength = packet->
length;
3127 sock =
socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
3131 (
errmsg(
"could not create RADIUS socket: %m")));
3136 memset(&localaddr, 0,
sizeof(localaddr));
3138 localaddr.sin6_family = serveraddrs[0].
ai_family;
3139 localaddr.sin6_addr = in6addr_any;
3140 if (localaddr.sin6_family == AF_INET6)
3141 addrsize =
sizeof(
struct sockaddr_in6);
3143 addrsize =
sizeof(
struct sockaddr_in);
3145 localaddr.sin_family = serveraddrs[0].
ai_family;
3146 localaddr.sin_addr.s_addr = INADDR_ANY;
3147 addrsize =
sizeof(
struct sockaddr_in);
3150 if (
bind(sock, (
struct sockaddr *) &localaddr, addrsize))
3153 (
errmsg(
"could not bind local RADIUS socket: %m")));
3159 if (sendto(sock, radius_buffer, packetlength, 0,
3160 serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
3163 (
errmsg(
"could not send RADIUS packet: %m")));
3187 struct timeval timeout;
3190 const char *errstr = NULL;
3193 timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (
now.tv_sec * 1000000 +
now.tv_usec);
3194 if (timeoutval <= 0)
3197 (
errmsg(
"timeout waiting for RADIUS response from %s",
3202 timeout.tv_sec = timeoutval / 1000000;
3203 timeout.tv_usec = timeoutval % 1000000;
3206 FD_SET(sock, &fdset);
3208 r =
select(sock + 1, &fdset, NULL, NULL, &timeout);
3216 (
errmsg(
"could not check status on RADIUS socket: %m")));
3223 (
errmsg(
"timeout waiting for RADIUS response from %s",
3240 addrsize =
sizeof(remoteaddr);
3242 (
struct sockaddr *) &remoteaddr, &addrsize);
3243 if (packetlength < 0)
3246 (
errmsg(
"could not read RADIUS response: %m")));
3259 (
errmsg(
"RADIUS response from %s was sent from incorrect port: %d",
3260 server,
pg_ntoh16(remoteaddr.sin6_port))));
3263 (
errmsg(
"RADIUS response from %s was sent from incorrect port: %d",
3264 server,
pg_ntoh16(remoteaddr.sin_port))));
3272 (
errmsg(
"RADIUS response from %s too short: %d", server, packetlength)));
3279 (
errmsg(
"RADIUS response from %s has corrupt length: %d (actual length %d)",
3284 if (packet->
id != receivepacket->
id)
3287 (
errmsg(
"RADIUS response from %s is to a different request: %d (should be %d)",
3288 server, receivepacket->
id, packet->
id)));
3296 cryptvector =
palloc(packetlength + strlen(secret));
3298 memcpy(cryptvector, receivepacket, 4);
3305 memcpy(cryptvector + packetlength, secret, strlen(secret));
3308 packetlength + strlen(secret),
3309 encryptedpassword, &errstr))
3312 (
errmsg(
"could not perform MD5 encryption of received packet: %s",
3322 (
errmsg(
"RADIUS response from %s has incorrect MD5 signature",
3340 (
errmsg(
"RADIUS response from %s has invalid code (%d) for user \"%s\"",
3341 server, receivepacket->
code, user_name)));
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 PG_MAX_AUTH_TOKEN_LENGTH
#define RADIUS_SERVICE_TYPE
static void set_authn_id(Port *port, const char *id)
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)
#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
void(* ClientAuthentication_hook_type)(Port *, int)
Datum now(PG_FUNCTION_ARGS)
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 offsetof(type, field)
#define FLEXIBLE_ARRAY_MEMBER
#define MemSet(start, val, len)
void(* pg_funcptr_t)(void)
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)
static void PGresult * res
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
int gettimeofday(struct timeval *tp, struct timezone *tzp)
bool pg_isblank(const char c)
const char * hba_authname(UserAuth auth_method)
int check_usermap(const char *usermap_name, const char *pg_role, const char *auth_user, bool case_insensitive)
void hba_getauthmethod(hbaPort *port)
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)
Assert(fmt[strlen(fmt) - 1] !='\n')
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * MemoryContextAllocZero(MemoryContext context, Size size)
char * MemoryContextStrdup(MemoryContext context, const char *string)
bool pg_md5_binary(const void *buff, size_t len, void *outbuf, const char **errstr)
#define CHECK_FOR_INTERRUPTS()
static int list_length(const List *l)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
static void static void status(const char *fmt,...) pg_attribute_printf(1
static void output(uint64 loop_count)
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 AUTH_REQ_PASSWORD
#define AUTH_REQ_GSS_CONT
#define AUTH_REQ_SASL_FIN
char * psprintf(const char *fmt,...)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
struct sockaddr_storage addr
struct sockaddr * ai_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)