1329{
1332 char **err_msg = &tok_line->
err_msg;
1334 struct addrinfo *gai_result;
1335 struct addrinfo hints;
1336 int ret;
1337 char *cidr_slash;
1338 char *unsupauth;
1344
1349
1350 /* Check the record type. */
1355 {
1357 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1358 errmsg(
"multiple values specified for connection type"),
1359 errhint(
"Specify exactly one connection type per line."),
1360 errcontext(
"line %d of configuration file \"%s\"",
1361 line_num, file_name)));
1362 *err_msg = "multiple values specified for connection type";
1363 return NULL;
1364 }
1366 if (strcmp(
token->string,
"local") == 0)
1367 {
1369 }
1370 else if (strcmp(
token->string,
"host") == 0 ||
1371 strcmp(
token->string,
"hostssl") == 0 ||
1372 strcmp(
token->string,
"hostnossl") == 0 ||
1373 strcmp(
token->string,
"hostgssenc") == 0 ||
1374 strcmp(
token->string,
"hostnogssenc") == 0)
1375 {
1376
1377 if (
token->string[4] ==
's')
/* "hostssl" */
1378 {
1380 /* Log a warning if SSL support is not active */
1381#ifdef USE_SSL
1383 {
1385 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1386 errmsg(
"hostssl record cannot match because SSL is disabled"),
1387 errhint(
"Set \"ssl = on\" in postgresql.conf."),
1388 errcontext(
"line %d of configuration file \"%s\"",
1389 line_num, file_name)));
1390 *err_msg = "hostssl record cannot match because SSL is disabled";
1391 }
1392#else
1394 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1395 errmsg(
"hostssl record cannot match because SSL is not supported by this build"),
1396 errcontext(
"line %d of configuration file \"%s\"",
1397 line_num, file_name)));
1398 *err_msg = "hostssl record cannot match because SSL is not supported by this build";
1399#endif
1400 }
1401 else if (
token->string[4] ==
'g')
/* "hostgssenc" */
1402 {
1404#ifndef ENABLE_GSS
1406 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1407 errmsg(
"hostgssenc record cannot match because GSSAPI is not supported by this build"),
1408 errcontext(
"line %d of configuration file \"%s\"",
1409 line_num, file_name)));
1410 *err_msg = "hostgssenc record cannot match because GSSAPI is not supported by this build";
1411#endif
1412 }
1413 else if (
token->string[4] ==
'n' &&
token->string[6] ==
's')
1415 else if (
token->string[4] ==
'n' &&
token->string[6] ==
'g')
1417 else
1418 {
1419 /* "host" */
1421 }
1422 } /* record type */
1423 else
1424 {
1426 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1427 errmsg(
"invalid connection type \"%s\"",
1429 errcontext(
"line %d of configuration file \"%s\"",
1430 line_num, file_name)));
1431 *err_msg =
psprintf(
"invalid connection type \"%s\"",
token->string);
1432 return NULL;
1433 }
1434
1435 /* Get the databases. */
1437 if (!field)
1438 {
1440 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1441 errmsg(
"end-of-line before database specification"),
1442 errcontext(
"line %d of configuration file \"%s\"",
1443 line_num, file_name)));
1444 *err_msg = "end-of-line before database specification";
1445 return NULL;
1446 }
1449 foreach(tokencell, tokens)
1450 {
1452
1453 /* Compile a regexp for the database token, if necessary */
1455 return NULL;
1456
1458 }
1459
1460 /* Get the roles. */
1462 if (!field)
1463 {
1465 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1466 errmsg(
"end-of-line before role specification"),
1467 errcontext(
"line %d of configuration file \"%s\"",
1468 line_num, file_name)));
1469 *err_msg = "end-of-line before role specification";
1470 return NULL;
1471 }
1474 foreach(tokencell, tokens)
1475 {
1477
1478 /* Compile a regexp from the role token, if necessary */
1480 return NULL;
1481
1483 }
1484
1486 {
1487 /* Read the IP address field. (with or without CIDR netmask) */
1489 if (!field)
1490 {
1492 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1493 errmsg(
"end-of-line before IP address specification"),
1494 errcontext(
"line %d of configuration file \"%s\"",
1495 line_num, file_name)));
1496 *err_msg = "end-of-line before IP address specification";
1497 return NULL;
1498 }
1501 {
1503 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1504 errmsg(
"multiple values specified for host address"),
1505 errhint(
"Specify one address range per line."),
1506 errcontext(
"line %d of configuration file \"%s\"",
1507 line_num, file_name)));
1508 *err_msg = "multiple values specified for host address";
1509 return NULL;
1510 }
1512
1514 {
1516 }
1518 {
1519 /* Any IP on this host is allowed to connect */
1521 }
1523 {
1524 /* Any IP on the host's subnets is allowed to connect */
1526 }
1527 else
1528 {
1529 /* IP and netmask are specified */
1531
1532 /* need a modifiable copy of token */
1534
1535 /* Check if it has a CIDR suffix and if so isolate it */
1536 cidr_slash = strchr(
str,
'/');
1537 if (cidr_slash)
1538 *cidr_slash = '0円';
1539
1540 /* Get the IP address either way */
1541 hints.ai_flags = AI_NUMERICHOST;
1542 hints.ai_family = AF_UNSPEC;
1543 hints.ai_socktype = 0;
1544 hints.ai_protocol = 0;
1545 hints.ai_addrlen = 0;
1546 hints.ai_canonname = NULL;
1547 hints.ai_addr = NULL;
1548 hints.ai_next = NULL;
1549
1551 if (ret == 0 && gai_result)
1552 {
1553 memcpy(&parsedline->
addr, gai_result->ai_addr,
1554 gai_result->ai_addrlen);
1555 parsedline->
addrlen = gai_result->ai_addrlen;
1556 }
1557 else if (ret == EAI_NONAME)
1559 else
1560 {
1562 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1563 errmsg(
"invalid IP address \"%s\": %s",
1565 errcontext(
"line %d of configuration file \"%s\"",
1566 line_num, file_name)));
1567 *err_msg =
psprintf(
"invalid IP address \"%s\": %s",
1569 if (gai_result)
1571 return NULL;
1572 }
1573
1575
1576 /* Get the netmask */
1577 if (cidr_slash)
1578 {
1580 {
1582 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1583 errmsg(
"specifying both host name and CIDR mask is invalid: \"%s\"",
1585 errcontext(
"line %d of configuration file \"%s\"",
1586 line_num, file_name)));
1587 *err_msg =
psprintf(
"specifying both host name and CIDR mask is invalid: \"%s\"",
1589 return NULL;
1590 }
1591
1593 parsedline->
addr.ss_family) < 0)
1594 {
1596 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1597 errmsg(
"invalid CIDR mask in address \"%s\"",
1599 errcontext(
"line %d of configuration file \"%s\"",
1600 line_num, file_name)));
1601 *err_msg =
psprintf(
"invalid CIDR mask in address \"%s\"",
1603 return NULL;
1604 }
1607 }
1609 {
1610 /* Read the mask field. */
1613 if (!field)
1614 {
1616 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1617 errmsg(
"end-of-line before netmask specification"),
1618 errhint(
"Specify an address range in CIDR notation, or provide a separate netmask."),
1619 errcontext(
"line %d of configuration file \"%s\"",
1620 line_num, file_name)));
1621 *err_msg = "end-of-line before netmask specification";
1622 return NULL;
1623 }
1626 {
1628 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1629 errmsg(
"multiple values specified for netmask"),
1630 errcontext(
"line %d of configuration file \"%s\"",
1631 line_num, file_name)));
1632 *err_msg = "multiple values specified for netmask";
1633 return NULL;
1634 }
1636
1638 &hints, &gai_result);
1639 if (ret || !gai_result)
1640 {
1642 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1643 errmsg(
"invalid IP mask \"%s\": %s",
1645 errcontext(
"line %d of configuration file \"%s\"",
1646 line_num, file_name)));
1647 *err_msg =
psprintf(
"invalid IP mask \"%s\": %s",
1649 if (gai_result)
1651 return NULL;
1652 }
1653
1654 memcpy(&parsedline->
mask, gai_result->ai_addr,
1655 gai_result->ai_addrlen);
1656 parsedline->
masklen = gai_result->ai_addrlen;
1658
1659 if (parsedline->
addr.ss_family != parsedline->
mask.ss_family)
1660 {
1662 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1663 errmsg(
"IP address and mask do not match"),
1664 errcontext(
"line %d of configuration file \"%s\"",
1665 line_num, file_name)));
1666 *err_msg = "IP address and mask do not match";
1667 return NULL;
1668 }
1669 }
1670 }
1671 } /* != ctLocal */
1672
1673 /* Get the authentication method */
1675 if (!field)
1676 {
1678 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1679 errmsg(
"end-of-line before authentication method"),
1680 errcontext(
"line %d of configuration file \"%s\"",
1681 line_num, file_name)));
1682 *err_msg = "end-of-line before authentication method";
1683 return NULL;
1684 }
1687 {
1689 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1690 errmsg(
"multiple values specified for authentication type"),
1691 errhint(
"Specify exactly one authentication type per line."),
1692 errcontext(
"line %d of configuration file \"%s\"",
1693 line_num, file_name)));
1694 *err_msg = "multiple values specified for authentication type";
1695 return NULL;
1696 }
1698
1699 unsupauth = NULL;
1700 if (strcmp(
token->string,
"trust") == 0)
1702 else if (strcmp(
token->string,
"ident") == 0)
1704 else if (strcmp(
token->string,
"peer") == 0)
1706 else if (strcmp(
token->string,
"password") == 0)
1708 else if (strcmp(
token->string,
"gss") == 0)
1709#ifdef ENABLE_GSS
1711#else
1712 unsupauth = "gss";
1713#endif
1714 else if (strcmp(
token->string,
"sspi") == 0)
1715#ifdef ENABLE_SSPI
1717#else
1718 unsupauth = "sspi";
1719#endif
1720 else if (strcmp(
token->string,
"reject") == 0)
1722 else if (strcmp(
token->string,
"md5") == 0)
1724 else if (strcmp(
token->string,
"scram-sha-256") == 0)
1726 else if (strcmp(
token->string,
"pam") == 0)
1727#ifdef USE_PAM
1729#else
1730 unsupauth = "pam";
1731#endif
1732 else if (strcmp(
token->string,
"bsd") == 0)
1733#ifdef USE_BSD_AUTH
1735#else
1736 unsupauth = "bsd";
1737#endif
1738 else if (strcmp(
token->string,
"ldap") == 0)
1739#ifdef USE_LDAP
1741#else
1742 unsupauth = "ldap";
1743#endif
1744 else if (strcmp(
token->string,
"cert") == 0)
1745#ifdef USE_SSL
1747#else
1748 unsupauth = "cert";
1749#endif
1750 else if (strcmp(
token->string,
"radius") == 0)
1752 else if (strcmp(
token->string,
"oauth") == 0)
1754 else
1755 {
1757 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1758 errmsg(
"invalid authentication method \"%s\"",
1760 errcontext(
"line %d of configuration file \"%s\"",
1761 line_num, file_name)));
1762 *err_msg =
psprintf(
"invalid authentication method \"%s\"",
1764 return NULL;
1765 }
1766
1767 if (unsupauth)
1768 {
1770 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1771 errmsg(
"invalid authentication method \"%s\": not supported by this build",
1773 errcontext(
"line %d of configuration file \"%s\"",
1774 line_num, file_name)));
1775 *err_msg =
psprintf(
"invalid authentication method \"%s\": not supported by this build",
1777 return NULL;
1778 }
1779
1780 /*
1781 * XXX: When using ident on local connections, change it to peer, for
1782 * backwards compatibility.
1783 */
1787
1788 /* Invalid authentication combinations */
1791 {
1793 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1794 errmsg(
"gssapi authentication is not supported on local sockets"),
1795 errcontext(
"line %d of configuration file \"%s\"",
1796 line_num, file_name)));
1797 *err_msg = "gssapi authentication is not supported on local sockets";
1798 return NULL;
1799 }
1800
1803 {
1805 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1806 errmsg(
"peer authentication is only supported on local sockets"),
1807 errcontext(
"line %d of configuration file \"%s\"",
1808 line_num, file_name)));
1809 *err_msg = "peer authentication is only supported on local sockets";
1810 return NULL;
1811 }
1812
1813 /*
1814 * SSPI authentication can never be enabled on ctLocal connections,
1815 * because it's only supported on Windows, where ctLocal isn't supported.
1816 */
1817
1818
1821 {
1823 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1824 errmsg(
"cert authentication is only supported on hostssl connections"),
1825 errcontext(
"line %d of configuration file \"%s\"",
1826 line_num, file_name)));
1827 *err_msg = "cert authentication is only supported on hostssl connections";
1828 return NULL;
1829 }
1830
1831 /*
1832 * For GSS and SSPI, set the default value of include_realm to true.
1833 * Having include_realm set to false is dangerous in multi-realm
1834 * situations and is generally considered bad practice. We keep the
1835 * capability around for backwards compatibility, but we might want to
1836 * remove it at some point in the future. Users who still need to strip
1837 * the realm off would be better served by using an appropriate regex in a
1838 * pg_ident.conf mapping.
1839 */
1843
1844 /*
1845 * For SSPI, include_realm defaults to the SAM-compatible domain (aka
1846 * NetBIOS name) and user names instead of the Kerberos principal name for
1847 * compatibility.
1848 */
1850 {
1853 }
1854
1855 /* Parse remaining arguments */
1856 while ((field =
lnext(tok_line->
fields, field)) != NULL)
1857 {
1859 foreach(tokencell, tokens)
1860 {
1862
1864
1868 {
1869 /*
1870 * Got something that's not a name=value pair.
1871 */
1873 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1874 errmsg(
"authentication option not in name=value format: %s",
token->string),
1875 errcontext(
"line %d of configuration file \"%s\"",
1876 line_num, file_name)));
1877 *err_msg =
psprintf(
"authentication option not in name=value format: %s",
1879 return NULL;
1880 }
1881
1882 *
val++ =
'0円';
/* str now holds "name", val holds "value" */
1884 /* parse_hba_auth_opt already logged the error message */
1885 return NULL;
1887 }
1888 }
1889
1890 /*
1891 * Check if the selected authentication method has any mandatory arguments
1892 * that are not set.
1893 */
1895 {
1896#ifndef HAVE_LDAP_INITIALIZE
1897 /* Not mandatory for OpenLDAP, because it can use DNS SRV records */
1899#endif
1900
1901 /*
1902 * LDAP can operate in two modes: either with a direct bind, using
1903 * ldapprefix and ldapsuffix, or using a search+bind, using
1904 * ldapbasedn, ldapbinddn, ldapbindpasswd and one of
1905 * ldapsearchattribute or ldapsearchfilter. Disallow mixing these
1906 * parameters.
1907 */
1909 {
1915 {
1917 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1918 errmsg(
"cannot mix options for simple bind and search+bind modes"),
1919 errcontext(
"line %d of configuration file \"%s\"",
1920 line_num, file_name)));
1921 *err_msg = "cannot mix options for simple bind and search+bind modes";
1922 return NULL;
1923 }
1924 }
1926 {
1928 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1929 errmsg(
"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set"),
1930 errcontext(
"line %d of configuration file \"%s\"",
1931 line_num, file_name)));
1932 *err_msg = "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set";
1933 return NULL;
1934 }
1935
1936 /*
1937 * When using search+bind, you can either use a simple attribute
1938 * (defaulting to "uid") or a fully custom search filter. You can't
1939 * do both.
1940 */
1942 {
1944 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1945 errmsg(
"cannot use ldapsearchattribute together with ldapsearchfilter"),
1946 errcontext(
"line %d of configuration file \"%s\"",
1947 line_num, file_name)));
1948 *err_msg = "cannot use ldapsearchattribute together with ldapsearchfilter";
1949 return NULL;
1950 }
1951 }
1952
1954 {
1957
1959 {
1961 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1962 errmsg(
"list of RADIUS servers cannot be empty"),
1963 errcontext(
"line %d of configuration file \"%s\"",
1964 line_num, file_name)));
1965 *err_msg = "list of RADIUS servers cannot be empty";
1966 return NULL;
1967 }
1968
1970 {
1972 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1973 errmsg(
"list of RADIUS secrets cannot be empty"),
1974 errcontext(
"line %d of configuration file \"%s\"",
1975 line_num, file_name)));
1976 *err_msg = "list of RADIUS secrets cannot be empty";
1977 return NULL;
1978 }
1979
1980 /*
1981 * Verify length of option lists - each can be 0 (except for secrets,
1982 * but that's already checked above), 1 (use the same value
1983 * everywhere) or the same as the number of servers.
1984 */
1987 {
1989 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1990 errmsg(
"the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)",
1993 errcontext(
"line %d of configuration file \"%s\"",
1994 line_num, file_name)));
1995 *err_msg =
psprintf(
"the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)",
1998 return NULL;
1999 }
2003 {
2005 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2006 errmsg(
"the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2009 errcontext(
"line %d of configuration file \"%s\"",
2010 line_num, file_name)));
2011 *err_msg =
psprintf(
"the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2014 return NULL;
2015 }
2019 {
2021 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2022 errmsg(
"the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2025 errcontext(
"line %d of configuration file \"%s\"",
2026 line_num, file_name)));
2027 *err_msg =
psprintf(
"the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2030 return NULL;
2031 }
2032 }
2033
2034 /*
2035 * Enforce any parameters implied by other settings.
2036 */
2038 {
2039 /*
2040 * For auth method cert, client certificate validation is mandatory,
2041 * and it implies the level of verify-full.
2042 */
2044 }
2045
2046 /*
2047 * Enforce proper configuration of OAuth authentication.
2048 */
2050 {
2053
2054 /* Ensure a validator library is set and permitted by the config. */
2056 return NULL;
2057
2058 /*
2059 * Supplying a usermap combined with the option to skip usermapping is
2060 * nonsensical and indicates a configuration error.
2061 */
2063 {
2065 errcode(ERRCODE_CONFIG_FILE_ERROR),
2066 /* translator: strings are replaced with hba options */
2067 errmsg(
"%s cannot be used in combination with %s",
2068 "map", "delegate_ident_mapping"),
2069 errcontext(
"line %d of configuration file \"%s\"",
2070 line_num, file_name));
2071 *err_msg = "map cannot be used in combination with delegate_ident_mapping";
2072 return NULL;
2073 }
2074 }
2075
2076 return parsedline;
2077}
bool check_oauth_validator(HbaLine *hbaline, int elevel, char **err_msg)
int errhint(const char *fmt,...)
#define MANDATORY_AUTH_ARG(argvar, argname, authname)
#define token_is_keyword(t, k)
static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg)
static int regcomp_auth_token(AuthToken *token, char *filename, int line_num, char **err_msg, int elevel)
static AuthToken * copy_auth_token(AuthToken *in)
int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
static int list_length(const List *l)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
const char * gai_strerror(int ecode)
struct sockaddr_storage mask
ClientCertMode clientcert
char * ldapsearchattribute
struct sockaddr_storage addr
IPCompareMethod ip_cmp_method