22 #ifdef HAVE_SYS_SELECT_H 23 #include <sys/select.h> 68 #define IDENT_USERNAME_MAX 512 71 #define IDENT_PORT 113 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" 98 static int pam_passwd_conv_proc(
int num_msg,
const struct pam_message **msg,
99 struct pam_response **resp,
void *appdata_ptr);
101 static struct pam_conv pam_passw_conv = {
102 &pam_passwd_conv_proc,
106 static const char *pam_passwd = NULL;
108 static Port *pam_port_cludge;
110 static bool pam_no_password;
119 #include <bsd_auth.h> 132 #define LDAP_DEPRECATED 1 139 ULONG (*__ldap_start_tls_sA) (IN PLDAP ExternalHandle,
140 OUT PULONG ServerReturnValue,
141 OUT LDAPMessage **result,
142 IN PLDAPControlA * ServerControls,
143 IN PLDAPControlA * ClientControls
147 static int CheckLDAPAuth(
Port *
port);
150 #ifndef LDAP_OPT_DIAGNOSTIC_MESSAGE 151 #define LDAP_OPT_DIAGNOSTIC_MESSAGE LDAP_OPT_ERROR_STRING 161 static int CheckCertAuth(
Port *
port);
180 static int pg_GSS_checkauth(
Port *
port);
181 static int pg_GSS_recvauth(
Port *
port);
190 typedef SECURITY_STATUS
191 (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) (PCtxtHandle,
void **);
192 static int pg_SSPI_recvauth(
Port *
port);
193 static int pg_SSPI_make_upn(
char *accountname,
194 size_t accountnamesize,
196 size_t domainnamesize,
197 bool update_accountname);
205 static int PerformRadiusTransaction(
const char *server,
const char *secret,
const char *portstr,
const char *identifier,
const char *user_name,
const char *passwd);
221 #define PG_MAX_AUTH_TOKEN_LENGTH 65535 229 #define PG_MAX_SASL_MESSAGE_LENGTH 1024 261 int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
280 errstr =
gettext_noop(
"authentication failed for user \"%s\": host rejected");
283 errstr =
gettext_noop(
"\"trust\" authentication failed for user \"%s\"");
286 errstr =
gettext_noop(
"Ident authentication failed for user \"%s\"");
289 errstr =
gettext_noop(
"Peer authentication failed for user \"%s\"");
294 errstr =
gettext_noop(
"password authentication failed for user \"%s\"");
299 errstr =
gettext_noop(
"GSSAPI authentication failed for user \"%s\"");
302 errstr =
gettext_noop(
"SSPI authentication failed for user \"%s\"");
305 errstr =
gettext_noop(
"PAM authentication failed for user \"%s\"");
308 errstr =
gettext_noop(
"BSD authentication failed for user \"%s\"");
311 errstr =
gettext_noop(
"LDAP authentication failed for user \"%s\"");
314 errstr =
gettext_noop(
"certificate authentication failed for user \"%s\"");
317 errstr =
gettext_noop(
"RADIUS authentication failed for user \"%s\"");
320 errstr =
gettext_noop(
"authentication failed for user \"%s\": invalid authentication method");
324 cdetail =
psprintf(
_(
"Connection matched pg_hba.conf line %d: \"%s\""),
327 logdetail =
psprintf(
"%s\n%s", logdetail, cdetail);
348 char *logdetail = NULL;
370 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
371 errmsg(
"client certificates can only be checked if a root certificate store is available")));
381 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
382 errmsg(
"connection requires a valid client certificate")));
404 const char *encryption_state;
407 hostinfo,
sizeof(hostinfo),
413 (port->
gss && port->
gss->enc) ?
_(
"GSS encryption") :
422 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
424 errmsg(
"pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
429 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
431 errmsg(
"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
450 const char *encryption_state;
453 hostinfo,
sizeof(hostinfo),
459 (port->
gss && port->
gss->enc) ?
_(
"GSS encryption") :
466 #define HOSTNAME_LOOKUP_DETAIL(port) \ 467 (port->remote_hostname ? \ 468 (port->remote_hostname_resolv == +1 ? \ 469 errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \ 470 port->remote_hostname) : \ 471 port->remote_hostname_resolv == 0 ? \ 472 errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \ 473 port->remote_hostname) : \ 474 port->remote_hostname_resolv == -1 ? \ 475 errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \ 476 port->remote_hostname) : \ 477 port->remote_hostname_resolv == -2 ? \ 478 errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \ 479 port->remote_hostname, \ 480 gai_strerror(port->remote_hostname_errcode)) : \ 482 : (port->remote_hostname_resolv == -2 ? \ 483 errdetail_log("Could not resolve client IP address to a host name: %s.", \ 484 gai_strerror(port->remote_hostname_errcode)) : \ 489 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
491 errmsg(
"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
497 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
499 errmsg(
"no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
510 if (port->
gss == NULL)
511 port->
gss = (pg_gssinfo *)
514 port->
gss->auth =
true;
521 status = pg_GSS_checkauth(port);
525 status = pg_GSS_recvauth(port);
534 if (port->
gss == NULL)
535 port->
gss = (pg_gssinfo *)
539 status = pg_SSPI_recvauth(port);
564 status = CheckPAMAuth(port, port->
user_name,
"");
572 status = CheckBSDAuth(port, port->
user_name);
580 status = CheckLDAPAuth(port);
603 status = CheckCertAuth(port);
674 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
675 errmsg(
"expected password response, got message type %d",
700 if (strlen(buf.
data) + 1 != buf.
len)
702 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
703 errmsg(
"invalid password packet size")));
721 errmsg(
"empty password returned by client")));
812 auth_result =
CheckMD5Auth(port, shadow_pass, logdetail);
840 (
errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
841 errmsg(
"MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
847 (
errmsg(
"could not generate random MD5 salt")));
859 md5Salt, 4, logdetail);
874 void *scram_opaq = NULL;
892 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
893 errmsg(
"SASL authentication is not supported in protocol version 2")));
925 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
926 errmsg(
"expected SASL response, got message type %d",
942 elog(
DEBUG4,
"processing received SASL response of length %d", buf.
len);
952 const char *selected_mech;
989 Assert(input == NULL || input[inputlen] ==
'\0');
1007 elog(
DEBUG4,
"sending SASL challenge of length %u", outputlen);
1042 gss_buffer_desc gbuf;
1054 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1055 errmsg(
"GSSAPI is not supported in protocol version 2")));
1067 (
errcode(ERRCODE_OUT_OF_MEMORY),
1068 errmsg(
"could not set environment: %m")));
1078 port->
gss->cred = GSS_C_NO_CREDENTIAL;
1083 port->
gss->ctx = GSS_C_NO_CONTEXT;
1103 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
1104 errmsg(
"expected GSS response, got message type %d",
1119 gbuf.length = buf.
len;
1120 gbuf.value = buf.
data;
1122 elog(
DEBUG4,
"processing received GSS token of length %u",
1123 (
unsigned int) gbuf.length);
1125 maj_stat = gss_accept_sec_context(&min_stat,
1129 GSS_C_NO_CHANNEL_BINDINGS,
1140 elog(
DEBUG5,
"gss_accept_sec_context major: %d, " 1141 "minor: %d, outlen: %u, outflags: %x",
1143 (
unsigned int) port->
gss->outbuf.length, gflags);
1147 if (port->
gss->outbuf.length != 0)
1152 elog(
DEBUG4,
"sending GSS response token of length %u",
1153 (
unsigned int) port->
gss->outbuf.length);
1156 port->
gss->outbuf.value, port->
gss->outbuf.length);
1158 gss_release_buffer(&lmin_s, &port->
gss->outbuf);
1161 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
1163 gss_delete_sec_context(&lmin_s, &port->
gss->ctx, GSS_C_NO_BUFFER);
1165 maj_stat, min_stat);
1169 if (maj_stat == GSS_S_CONTINUE_NEEDED)
1172 }
while (maj_stat == GSS_S_CONTINUE_NEEDED);
1174 if (port->
gss->cred != GSS_C_NO_CREDENTIAL)
1179 gss_release_cred(&min_stat, &port->
gss->cred);
1181 return pg_GSS_checkauth(port);
1189 pg_GSS_checkauth(
Port *port)
1195 gss_buffer_desc gbuf;
1201 maj_stat = gss_display_name(&min_stat, port->
gss->name, &gbuf, NULL);
1202 if (maj_stat != GSS_S_COMPLETE)
1205 maj_stat, min_stat);
1218 if (strchr(gbuf.value,
'@'))
1220 char *cp = strchr(gbuf.value,
'@');
1245 "GSSAPI realm (%s) and configured realm (%s) don't match",
1247 gss_release_buffer(&lmin_s, &gbuf);
1255 "GSSAPI did not return realm but realm matching was requested");
1257 gss_release_buffer(&lmin_s, &gbuf);
1264 gss_release_buffer(&lmin_s, &gbuf);
1282 pg_SSPI_error(
int severity,
const char *
errmsg, SECURITY_STATUS r)
1286 if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
1287 FORMAT_MESSAGE_FROM_SYSTEM,
1289 sysmsg,
sizeof(sysmsg), NULL) == 0)
1300 pg_SSPI_recvauth(
Port *port)
1305 CredHandle sspicred;
1306 CtxtHandle *sspictx = NULL,
1310 SecBufferDesc inbuf;
1311 SecBufferDesc outbuf;
1312 SecBuffer OutBuffers[1];
1313 SecBuffer InBuffers[1];
1315 TOKEN_USER *tokenuser;
1319 DWORD accountnamesize =
sizeof(accountname);
1320 DWORD domainnamesize =
sizeof(domainname);
1321 SID_NAME_USE accountnameuse;
1324 QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
1336 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1337 errmsg(
"SSPI is not supported in protocol version 2")));
1342 r = AcquireCredentialsHandle(NULL,
1344 SECPKG_CRED_INBOUND,
1352 pg_SSPI_error(
ERROR,
_(
"could not acquire SSPI credentials"), r);
1366 if (sspictx != NULL)
1368 DeleteSecurityContext(sspictx);
1371 FreeCredentialsHandle(&sspicred);
1376 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
1377 errmsg(
"expected SSPI response, got message type %d",
1388 if (sspictx != NULL)
1390 DeleteSecurityContext(sspictx);
1393 FreeCredentialsHandle(&sspicred);
1398 inbuf.ulVersion = SECBUFFER_VERSION;
1400 inbuf.pBuffers = InBuffers;
1401 InBuffers[0].pvBuffer = buf.
data;
1402 InBuffers[0].cbBuffer = buf.
len;
1403 InBuffers[0].BufferType = SECBUFFER_TOKEN;
1406 OutBuffers[0].pvBuffer = NULL;
1407 OutBuffers[0].BufferType = SECBUFFER_TOKEN;
1408 OutBuffers[0].cbBuffer = 0;
1409 outbuf.cBuffers = 1;
1410 outbuf.pBuffers = OutBuffers;
1411 outbuf.ulVersion = SECBUFFER_VERSION;
1413 elog(
DEBUG4,
"processing received SSPI token of length %u",
1414 (
unsigned int) buf.
len);
1416 r = AcceptSecurityContext(&sspicred,
1419 ASC_REQ_ALLOCATE_MEMORY,
1420 SECURITY_NETWORK_DREP,
1429 if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
1434 elog(
DEBUG4,
"sending SSPI response token of length %u",
1435 (
unsigned int) outbuf.pBuffers[0].cbBuffer);
1437 port->
gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
1438 port->
gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;
1441 port->
gss->outbuf.value, port->
gss->outbuf.length);
1443 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
1446 if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
1448 if (sspictx != NULL)
1450 DeleteSecurityContext(sspictx);
1453 FreeCredentialsHandle(&sspicred);
1454 pg_SSPI_error(
ERROR,
1455 _(
"could not accept SSPI security context"), r);
1464 if (sspictx == NULL)
1466 sspictx =
malloc(
sizeof(CtxtHandle));
1467 if (sspictx == NULL)
1469 (
errmsg(
"out of memory")));
1472 memcpy(sspictx, &newctx,
sizeof(CtxtHandle));
1474 if (r == SEC_I_CONTINUE_NEEDED)
1477 }
while (r == SEC_I_CONTINUE_NEEDED);
1483 FreeCredentialsHandle(&sspicred);
1496 secur32 = LoadLibrary(
"SECUR32.DLL");
1497 if (secur32 == NULL)
1499 (
errmsg(
"could not load library \"%s\": error code %lu",
1500 "SECUR32.DLL", GetLastError())));
1502 _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN) (
pg_funcptr_t)
1503 GetProcAddress(secur32,
"QuerySecurityContextToken");
1504 if (_QuerySecurityContextToken == NULL)
1506 FreeLibrary(secur32);
1508 (
errmsg_internal(
"could not locate QuerySecurityContextToken in secur32.dll: error code %lu",
1512 r = (_QuerySecurityContextToken) (sspictx, &token);
1515 FreeLibrary(secur32);
1516 pg_SSPI_error(
ERROR,
1517 _(
"could not get token from SSPI security context"), r);
1520 FreeLibrary(secur32);
1526 DeleteSecurityContext(sspictx);
1529 if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
1531 (
errmsg_internal(
"could not get token information buffer size: error code %lu",
1534 tokenuser =
malloc(retlen);
1535 if (tokenuser == NULL)
1537 (
errmsg(
"out of memory")));
1539 if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
1546 if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
1547 domainname, &domainnamesize, &accountnameuse))
1556 int status = pg_SSPI_make_upn(accountname,
sizeof(accountname),
1557 domainname,
sizeof(domainname),
1574 "SSPI domain (%s) and configured domain (%s) don't match",
1592 namebuf =
psprintf(
"%s@%s", accountname, domainname);
1606 pg_SSPI_make_upn(
char *accountname,
1607 size_t accountnamesize,
1609 size_t domainnamesize,
1610 bool update_accountname)
1613 char *upname = NULL;
1615 ULONG upnamesize = 0;
1616 size_t upnamerealmsize;
1626 samname =
psprintf(
"%s\\%s", domainname, accountname);
1627 res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
1630 if ((!res && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1635 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1636 errmsg(
"could not translate name")));
1641 upname =
palloc(upnamesize);
1643 res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
1644 upname, &upnamesize);
1648 p = strchr(upname,
'@');
1650 if (!res || p == NULL)
1654 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1655 errmsg(
"could not translate name")));
1660 upnamerealmsize = upnamesize - (p - upname + 1);
1663 if (upnamerealmsize > domainnamesize)
1667 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1668 errmsg(
"realm name too long")));
1673 strcpy(domainname, p + 1);
1676 if (update_accountname)
1678 if ((p - upname + 1) > accountnamesize)
1682 (
errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
1683 errmsg(
"translated account name too long")));
1688 strcpy(accountname, upname);
1713 const char *
cursor = ident_response;
1718 if (strlen(ident_response) < 2)
1720 else if (ident_response[strlen(ident_response) - 2] !=
'\r')
1724 while (*cursor !=
':' && *cursor !=
'\r')
1732 char response_type[80];
1739 while (*cursor !=
':' && *cursor !=
'\r' && !
pg_isblank(*cursor) &&
1740 i < (
int) (
sizeof(response_type) - 1))
1741 response_type[i++] = *cursor++;
1742 response_type[
i] =
'\0';
1745 if (strcmp(response_type,
"USERID") != 0)
1759 while (*cursor !=
':' && *cursor !=
'\r')
1773 ident_user[i++] = *cursor++;
1774 ident_user[
i] =
'\0';
1806 char ident_query[80];
1808 struct addrinfo *ident_serv = NULL,
1817 remote_addr_s,
sizeof(remote_addr_s),
1818 remote_port,
sizeof(remote_port),
1821 local_addr_s,
sizeof(local_addr_s),
1822 local_port,
sizeof(local_port),
1827 hints.ai_family = remote_addr.
addr.ss_family;
1828 hints.ai_socktype = SOCK_STREAM;
1829 hints.ai_protocol = 0;
1830 hints.ai_addrlen = 0;
1831 hints.ai_canonname = NULL;
1832 hints.ai_addr = NULL;
1833 hints.ai_next = NULL;
1835 if (rc || !ident_serv)
1838 ident_return =
false;
1839 goto ident_inet_done;
1843 hints.ai_family = local_addr.
addr.ss_family;
1844 hints.ai_socktype = SOCK_STREAM;
1845 hints.ai_protocol = 0;
1846 hints.ai_addrlen = 0;
1847 hints.ai_canonname = NULL;
1848 hints.ai_addr = NULL;
1849 hints.ai_next = NULL;
1854 ident_return =
false;
1855 goto ident_inet_done;
1864 errmsg(
"could not create socket for Ident connection: %m")));
1865 ident_return =
false;
1866 goto ident_inet_done;
1874 rc =
bind(sock_fd, la->ai_addr, la->ai_addrlen);
1879 errmsg(
"could not bind to local address \"%s\": %m",
1881 ident_return =
false;
1882 goto ident_inet_done;
1891 errmsg(
"could not connect to Ident server at address \"%s\", port %s: %m",
1892 remote_addr_s, ident_port)));
1893 ident_return =
false;
1894 goto ident_inet_done;
1898 snprintf(ident_query,
sizeof(ident_query),
"%s,%s\r\n",
1899 remote_port, local_port);
1906 rc =
send(sock_fd, ident_query, strlen(ident_query), 0);
1907 }
while (rc < 0 && errno ==
EINTR);
1913 errmsg(
"could not send query to Ident server at address \"%s\", port %s: %m",
1914 remote_addr_s, ident_port)));
1915 ident_return =
false;
1916 goto ident_inet_done;
1923 rc =
recv(sock_fd, ident_response,
sizeof(ident_response) - 1, 0);
1924 }
while (rc < 0 && errno ==
EINTR);
1930 errmsg(
"could not receive response from Ident server at address \"%s\", port %s: %m",
1931 remote_addr_s, ident_port)));
1932 ident_return =
false;
1933 goto ident_inet_done;
1936 ident_response[rc] =
'\0';
1940 (
errmsg(
"invalidly formatted response from Ident server: \"%s\"",
1984 if (errno == ENOSYS)
1986 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1987 errmsg(
"peer authentication is not supported on this platform")));
1991 errmsg(
"could not get peer credentials: %m")));
2000 int save_errno = errno;
2003 (
errmsg(
"could not look up local user ID %ld: %s",
2005 save_errno ?
strerror(save_errno) :
_(
"user does not exist"))));
2010 peer_user =
pstrdup(pw->pw_name);
2036 pam_passwd_conv_proc(
int num_msg,
const struct pam_message **msg,
2037 struct pam_response **resp,
void *appdata_ptr)
2040 struct pam_response *reply;
2044 passwd = (
char *) appdata_ptr;
2051 passwd = pam_passwd;
2056 if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
2057 return PAM_CONV_ERR;
2063 if ((reply =
calloc(num_msg,
sizeof(
struct pam_response))) == NULL)
2066 (
errcode(ERRCODE_OUT_OF_MEMORY),
2067 errmsg(
"out of memory")));
2068 return PAM_CONV_ERR;
2071 for (i = 0; i < num_msg; i++)
2073 switch (msg[i]->msg_style)
2075 case PAM_PROMPT_ECHO_OFF:
2076 if (strlen(passwd) == 0)
2092 pam_no_password =
true;
2096 if ((reply[i].resp = strdup(passwd)) == NULL)
2098 reply[
i].resp_retcode = PAM_SUCCESS;
2102 (
errmsg(
"error from underlying PAM layer: %s",
2107 if ((reply[i].resp = strdup(
"")) == NULL)
2109 reply[
i].resp_retcode = PAM_SUCCESS;
2113 (
errmsg(
"unsupported PAM conversation %d/\"%s\"",
2115 msg[i]->msg ? msg[i]->msg :
"(none)")));
2125 for (i = 0; i < num_msg; i++)
2127 if (reply[i].resp != NULL)
2128 free(reply[i].resp);
2132 return PAM_CONV_ERR;
2143 pam_handle_t *pamh = NULL;
2151 pam_port_cludge =
port;
2152 pam_no_password =
false;
2159 pam_passw_conv.appdata_ptr =
unconstify(
char *, password);
2165 &pam_passw_conv, &pamh);
2167 retval = pam_start(PGSQL_PAM_SERVICE,
"pgsql@",
2168 &pam_passw_conv, &pamh);
2170 if (retval != PAM_SUCCESS)
2173 (
errmsg(
"could not create PAM authenticator: %s",
2174 pam_strerror(pamh, retval))));
2179 retval = pam_set_item(pamh, PAM_USER,
user);
2181 if (retval != PAM_SUCCESS)
2184 (
errmsg(
"pam_set_item(PAM_USER) failed: %s",
2185 pam_strerror(pamh, retval))));
2201 hostinfo,
sizeof(hostinfo), NULL, 0,
2211 retval = pam_set_item(pamh, PAM_RHOST, hostinfo);
2213 if (retval != PAM_SUCCESS)
2216 (
errmsg(
"pam_set_item(PAM_RHOST) failed: %s",
2217 pam_strerror(pamh, retval))));
2223 retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
2225 if (retval != PAM_SUCCESS)
2228 (
errmsg(
"pam_set_item(PAM_CONV) failed: %s",
2229 pam_strerror(pamh, retval))));
2234 retval = pam_authenticate(pamh, 0);
2236 if (retval != PAM_SUCCESS)
2239 if (!pam_no_password)
2241 (
errmsg(
"pam_authenticate failed: %s",
2242 pam_strerror(pamh, retval))));
2247 retval = pam_acct_mgmt(pamh, 0);
2249 if (retval != PAM_SUCCESS)
2252 if (!pam_no_password)
2254 (
errmsg(
"pam_acct_mgmt failed: %s",
2255 pam_strerror(pamh, retval))));
2260 retval = pam_end(pamh, retval);
2262 if (retval != PAM_SUCCESS)
2265 (
errmsg(
"could not release PAM authenticator: %s",
2266 pam_strerror(pamh, retval))));
2282 CheckBSDAuth(
Port *port,
char *
user)
2299 retval = auth_userokay(user, NULL,
"auth-postgresql", passwd);
2317 static int errdetail_for_ldap(LDAP *ldap);
2324 InitializeLDAPConnection(
Port *port, LDAP **ldap)
2327 int ldapversion = LDAP_VERSION3;
2334 if (strcmp(scheme,
"ldaps") == 0)
2341 (
errmsg(
"could not initialize LDAP: error code %d",
2342 (
int) LdapGetLastError())));
2347 #ifdef HAVE_LDAP_INITIALIZE 2358 char *hostlist = NULL;
2378 (
errmsg(
"could not extract domain name from ldapbasedn")));
2383 if (ldap_domain2hostlist(domain, &hostlist))
2386 (
errmsg(
"LDAP authentication could not find DNS SRV records for \"%s\"",
2388 (
errhint(
"Set an LDAP server name explicitly."))));
2389 ldap_memfree(domain);
2392 ldap_memfree(domain);
2396 append_port =
false;
2411 size = strcspn(p,
" ");
2432 ldap_memfree(hostlist);
2435 r = ldap_initialize(ldap, uris.
data);
2437 if (r != LDAP_SUCCESS)
2440 (
errmsg(
"could not initialize LDAP: %s",
2441 ldap_err2string(r))));
2447 if (strcmp(scheme,
"ldaps") == 0)
2450 (
errmsg(
"ldaps not supported with this LDAP library")));
2458 (
errmsg(
"could not initialize LDAP: %m")));
2465 if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
2468 (
errmsg(
"could not set LDAP protocol version: %s",
2469 ldap_err2string(r)),
2470 errdetail_for_ldap(*ldap)));
2478 if ((r = ldap_start_tls_s(*ldap, NULL, NULL)) != LDAP_SUCCESS)
2480 static __ldap_start_tls_sA _ldap_start_tls_sA = NULL;
2482 if (_ldap_start_tls_sA == NULL)
2491 ldaphandle = LoadLibrary(
"WLDAP32.DLL");
2492 if (ldaphandle == NULL)
2499 (
errmsg(
"could not load library \"%s\": error code %lu",
2500 "WLDAP32.DLL", GetLastError())));
2504 _ldap_start_tls_sA = (__ldap_start_tls_sA) (
pg_funcptr_t) GetProcAddress(ldaphandle,
"ldap_start_tls_sA");
2505 if (_ldap_start_tls_sA == NULL)
2508 (
errmsg(
"could not load function _ldap_start_tls_sA in wldap32.dll"),
2509 errdetail(
"LDAP over SSL is not supported on this platform.")));
2511 FreeLibrary(ldaphandle);
2521 if ((r = _ldap_start_tls_sA(*ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS)
2525 (
errmsg(
"could not start LDAP TLS session: %s",
2526 ldap_err2string(r)),
2527 errdetail_for_ldap(*ldap)));
2537 #define LPH_USERNAME "$username" 2538 #define LPH_USERNAME_LEN (sizeof(LPH_USERNAME) - 1) 2541 #ifndef LDAP_NO_ATTRS 2542 #define LDAP_NO_ATTRS "1.1" 2547 #define LDAPS_PORT 636 2555 FormatSearchFilter(
const char *pattern,
const char *user_name)
2560 while (*pattern !=
'\0')
2562 if (strncmp(pattern, LPH_USERNAME, LPH_USERNAME_LEN) == 0)
2565 pattern += LPH_USERNAME_LEN;
2578 CheckLDAPAuth(
Port *port)
2584 const char *server_name;
2586 #ifdef HAVE_LDAP_INITIALIZE 2596 (
errmsg(
"LDAP server not specified, and no ldapbasedn")));
2603 (
errmsg(
"LDAP server not specified")));
2629 if (InitializeLDAPConnection(port, &ldap) ==
STATUS_ERROR)
2643 LDAPMessage *search_message;
2645 char *attributes[] = {LDAP_NO_ATTRS, NULL};
2665 (
errmsg(
"invalid character in user name for LDAP authentication")));
2676 r = ldap_simple_bind_s(ldap,
2679 if (r != LDAP_SUCCESS)
2682 (
errmsg(
"could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s",
2685 ldap_err2string(r)),
2686 errdetail_for_ldap(ldap)));
2700 r = ldap_search_s(ldap,
2708 if (r != LDAP_SUCCESS)
2711 (
errmsg(
"could not search LDAP for filter \"%s\" on server \"%s\": %s",
2712 filter, server_name, ldap_err2string(r)),
2713 errdetail_for_ldap(ldap)));
2720 count = ldap_count_entries(ldap, search_message);
2726 errdetail(
"LDAP search for filter \"%s\" on server \"%s\" returned no entries.",
2727 filter, server_name)));
2731 errdetail_plural(
"LDAP search for filter \"%s\" on server \"%s\" returned %d entry.",
2732 "LDAP search for filter \"%s\" on server \"%s\" returned %d entries.",
2734 filter, server_name, count)));
2739 ldap_msgfree(search_message);
2743 entry = ldap_first_entry(ldap, search_message);
2744 dn = ldap_get_dn(ldap, entry);
2749 (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
2751 (
errmsg(
"could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
2752 filter, server_name,
2753 ldap_err2string(error)),
2754 errdetail_for_ldap(ldap)));
2758 ldap_msgfree(search_message);
2765 ldap_msgfree(search_message);
2768 r = ldap_unbind_s(ldap);
2769 if (r != LDAP_SUCCESS)
2772 (
errmsg(
"could not unbind after searching for user \"%s\" on server \"%s\"",
2773 fulluser, server_name)));
2783 if (InitializeLDAPConnection(port, &ldap) ==
STATUS_ERROR)
2798 r = ldap_simple_bind_s(ldap, fulluser, passwd);
2800 if (r != LDAP_SUCCESS)
2803 (
errmsg(
"LDAP login failed for user \"%s\" on server \"%s\": %s",
2804 fulluser, server_name, ldap_err2string(r)),
2805 errdetail_for_ldap(ldap)));
2824 errdetail_for_ldap(LDAP *ldap)
2829 rc = ldap_get_option(ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, &message);
2830 if (rc == LDAP_SUCCESS && message != NULL)
2832 errdetail(
"LDAP diagnostics: %s", message);
2833 ldap_memfree(message);
2848 CheckCertAuth(
Port *port)
2859 (
errmsg(
"certificate authentication failed for user \"%s\": client certificate contains no user name",
2876 (
errmsg(
"certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch",
2880 return status_check_usermap;
2894 #define RADIUS_VECTOR_LENGTH 16 2895 #define RADIUS_HEADER_LENGTH 20 2896 #define RADIUS_MAX_PASSWORD_LENGTH 128 2899 #define RADIUS_BUFFER_SIZE 1024 2919 #define RADIUS_ACCESS_REQUEST 1 2920 #define RADIUS_ACCESS_ACCEPT 2 2921 #define RADIUS_ACCESS_REJECT 3 2924 #define RADIUS_USER_NAME 1 2925 #define RADIUS_PASSWORD 2 2926 #define RADIUS_SERVICE_TYPE 6 2927 #define RADIUS_NAS_IDENTIFIER 32 2930 #define RADIUS_AUTHENTICATE_ONLY 8 2933 #define RADIUS_TIMEOUT 3 2949 "adding attribute code %d with length %d to radius packet would create oversize packet, ignoring",
2957 memcpy(attr->
data, data, len);
2977 (
errmsg(
"RADIUS server not specified")));
2984 (
errmsg(
"RADIUS secret not specified")));
3013 radiusports ?
lfirst(radiusports) : NULL,
3014 identifiers ?
lfirst(identifiers) : NULL,
3055 PerformRadiusTransaction(
const char *server,
const char *secret,
const char *portstr,
const char *identifier,
const char *user_name,
const char *passwd)
3061 char *radius_buffer = (
char *) &radius_send_pack;
3062 char *receive_buffer = (
char *) &radius_recv_pack;
3065 int encryptedpasswordlen;
3072 struct sockaddr_in6 localaddr;
3073 struct sockaddr_in6 remoteaddr;
3075 struct sockaddr_in localaddr;
3076 struct sockaddr_in remoteaddr;
3081 ACCEPT_TYPE_ARG3 addrsize;
3083 struct timeval endtime;
3089 if (portstr == NULL)
3091 if (identifier == NULL)
3092 identifier =
"postgresql";
3094 MemSet(&hint, 0,
sizeof(hint));
3097 port = atoi(portstr);
3100 if (r || !serveraddrs)
3103 (
errmsg(
"could not translate RADIUS server name \"%s\" to address: %s",
3117 (
errmsg(
"could not generate random encryption vector")));
3134 memcpy(cryptvector, secret, strlen(secret));
3137 md5trailer = packet->
vector;
3146 md5trailer = encryptedpassword +
i;
3151 (
errmsg(
"could not perform MD5 encryption of password")));
3159 if (j < strlen(passwd))
3160 encryptedpassword[j] = passwd[j] ^ encryptedpassword[j];
3162 encryptedpassword[j] =
'\0' ^ encryptedpassword[j];
3170 packetlength = packet->
length;
3173 sock =
socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
3177 (
errmsg(
"could not create RADIUS socket: %m")));
3182 memset(&localaddr, 0,
sizeof(localaddr));
3184 localaddr.sin6_family = serveraddrs[0].
ai_family;
3185 localaddr.sin6_addr = in6addr_any;
3186 if (localaddr.sin6_family == AF_INET6)
3187 addrsize =
sizeof(
struct sockaddr_in6);
3189 addrsize =
sizeof(
struct sockaddr_in);
3191 localaddr.sin_family = serveraddrs[0].
ai_family;
3192 localaddr.sin_addr.s_addr = INADDR_ANY;
3193 addrsize =
sizeof(
struct sockaddr_in);
3196 if (
bind(sock, (
struct sockaddr *) &localaddr, addrsize))
3199 (
errmsg(
"could not bind local RADIUS socket: %m")));
3205 if (sendto(sock, radius_buffer, packetlength, 0,
3206 serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
3209 (
errmsg(
"could not send RADIUS packet: %m")));
3233 struct timeval timeout;
3238 timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (now.tv_sec * 1000000 + now.tv_usec);
3239 if (timeoutval <= 0)
3242 (
errmsg(
"timeout waiting for RADIUS response from %s",
3247 timeout.tv_sec = timeoutval / 1000000;
3248 timeout.tv_usec = timeoutval % 1000000;
3251 FD_SET(sock, &fdset);
3253 r =
select(sock + 1, &fdset, NULL, NULL, &timeout);
3261 (
errmsg(
"could not check status on RADIUS socket: %m")));
3268 (
errmsg(
"timeout waiting for RADIUS response from %s",
3285 addrsize =
sizeof(remoteaddr);
3287 (
struct sockaddr *) &remoteaddr, &addrsize);
3288 if (packetlength < 0)
3291 (
errmsg(
"could not read RADIUS response: %m")));
3297 if (remoteaddr.sin6_port !=
pg_hton16(port))
3299 if (remoteaddr.sin_port !=
pg_hton16(port))
3304 (
errmsg(
"RADIUS response from %s was sent from incorrect port: %d",
3305 server,
pg_ntoh16(remoteaddr.sin6_port))));
3308 (
errmsg(
"RADIUS response from %s was sent from incorrect port: %d",
3309 server,
pg_ntoh16(remoteaddr.sin_port))));
3317 (
errmsg(
"RADIUS response from %s too short: %d", server, packetlength)));
3324 (
errmsg(
"RADIUS response from %s has corrupt length: %d (actual length %d)",
3329 if (packet->
id != receivepacket->
id)
3332 (
errmsg(
"RADIUS response from %s is to a different request: %d (should be %d)",
3333 server, receivepacket->
id, packet->
id)));
3341 cryptvector =
palloc(packetlength + strlen(secret));
3343 memcpy(cryptvector, receivepacket, 4);
3350 memcpy(cryptvector + packetlength, secret, strlen(secret));
3353 packetlength + strlen(secret),
3357 (
errmsg(
"could not perform MD5 encryption of received packet")));
3366 (
errmsg(
"RADIUS response from %s has incorrect MD5 signature",
3384 (
errmsg(
"RADIUS response from %s has invalid code (%d) for user \"%s\"",
3385 server, receivepacket->
code, user_name)));
#define HOSTNAME_LOOKUP_DETAIL(port)
static int auth_peer(hbaPort *port)
int gettimeofday(struct timeval *tp, struct timezone *tzp)
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
int errhint(const char *fmt,...)
void pg_be_scram_get_mechanisms(Port *port, StringInfo buf)
bool pg_isblank(const char c)
bool pg_md5_binary(const void *buff, size_t len, void *outbuf)
static ListCell * lnext(const List *l, const ListCell *c)
static void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extralen)
#define AUTH_REQ_SASL_FIN
static void output(uint64 loop_count)
int getpeereid(int sock, uid_t *uid, gid_t *gid)
void ClientAuthentication(Port *port)
char * pstrdup(const char *in)
char * psprintf(const char *fmt,...)
struct sockaddr_storage addr
#define RADIUS_VECTOR_LENGTH
#define SASL_EXCHANGE_SUCCESS
#define FLEXIBLE_ARRAY_MEMBER
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, char **logdetail)
int errcode(int sqlerrcode)
#define MemSet(start, val, len)
#define connect(s, name, namelen)
int pg_strcasecmp(const char *s1, const char *s2)
static int CheckRADIUSAuth(Port *port)
#define RADIUS_NAS_IDENTIFIER
#define PG_PROTOCOL_MAJOR(v)
#define bind(s, addr, addrlen)
#define recv(s, buf, len, flags)
int errdetail_internal(const char *fmt,...)
#define RADIUS_HEADER_LENGTH
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
static int PerformRadiusTransaction(const char *server, const char *secret, const char *portstr, const char *identifier, const char *user_name, const char *passwd)
#define IDENT_USERNAME_MAX
void * pg_be_scram_init(Port *port, const char *selected_mech, const char *shadow_pass)
void pfree(void *pointer)
void appendStringInfo(StringInfo str, const char *fmt,...)
void pq_startmsgread(void)
static int CheckPWChallengeAuth(Port *port, char **logdetail)
static int CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail)
bool pg_krb_caseins_users
char * get_role_password(const char *role, char **logdetail)
void appendStringInfoString(StringInfo str, const char *s)
int errdetail(const char *fmt,...)
void hba_getauthmethod(hbaPort *port)
#define select(n, r, w, e, timeout)
ClientAuthentication_hook_type ClientAuthentication_hook
static ListCell * list_head(const List *l)
int errdetail_log(const char *fmt,...)
#define PG_MAX_AUTH_TOKEN_LENGTH
void(* ClientAuthentication_hook_type)(Port *, int)
MemoryContext TopMemoryContext
static char * recv_password_packet(Port *port)
int errcode_for_socket_access(void)
#define RADIUS_ACCESS_ACCEPT
#define AUTH_REQ_PASSWORD
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
static int CheckMD5Auth(Port *port, char *shadow_pass, char **logdetail)
static int ident_inet(hbaPort *port)
#define unconstify(underlying_type, expr)
int pq_getmessage(StringInfo s, int maxlen)
int md5_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const char *md5_salt, int md5_salt_len, char **logdetail)
#define RADIUS_BUFFER_SIZE
#define socket(af, type, protocol)
int pg_be_scram_exchange(void *opaq, const char *input, int inputlen, char **output, int *outputlen, char **logdetail)
#define RADIUS_AUTHENTICATE_ONLY
static int CheckPasswordAuth(Port *port, char **logdetail)
int check_usermap(const char *usermap_name, const char *pg_role, const char *auth_user, bool case_insensitive)
void * MemoryContextAllocZero(MemoryContext context, Size size)
#define AUTH_REQ_SASL_CONT
void pg_GSS_error(const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
#define ereport(elevel,...)
int errmsg_internal(const char *fmt,...)
bool pg_strong_random(void *buf, size_t len)
#define Assert(condition)
#define RADIUS_ACCESS_REQUEST
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
ClientCertMode clientcert
#define RADIUS_MAX_PASSWORD_LENGTH
static int list_length(const List *l)
#define RADIUS_SERVICE_TYPE
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
bool secure_loaded_verify_locations(void)
char * ldapsearchattribute
#define PG_MAX_SASL_MESSAGE_LENGTH
char * pg_krb_server_keyfile
#define AUTH_REQ_GSS_CONT
int errmsg(const char *fmt,...)
char * MemoryContextStrdup(MemoryContext context, const char *string)
static void auth_failed(Port *port, int status, char *logdetail)
PasswordType get_password_type(const char *shadow_pass)
uint8 data[FLEXIBLE_ARRAY_MEMBER]
uint8 vector[RADIUS_VECTOR_LENGTH]
void(* pg_funcptr_t)(void)
#define CHECK_FOR_INTERRUPTS()
#define SASL_EXCHANGE_CONTINUE
static void radius_add_attribute(radius_packet *packet, uint8 type, const unsigned char *data, int len)
static void static void status(const char *fmt,...) pg_attribute_printf(1
#define ERRCODE_INVALID_PASSWORD
static bool interpret_ident_response(const char *ident_response, char *ident_user)
ProtocolVersion FrontendProtocol
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
struct sockaddr * ai_addr
#define offsetof(type, field)
#define RADIUS_ACCESS_REJECT
#define send(s, buf, len, flags)