75 #define token_has_regexp(t) (t->regex != NULL)
76 #define token_is_member_check(t) (!t->quoted && t->string[0] == '+')
77 #define token_is_keyword(t, k) (!t->quoted && strcmp(t->string, k) == 0)
78 #define token_matches(t, k) (strcmp(t->string, k) == 0)
79 #define token_matches_insensitive(t,k) (pg_strcasecmp(t->string, k) == 0)
136 "UserAuthName[] must match the UserAuth enum");
140 const char *inc_filename,
int elevel,
141 int depth,
char **err_msg);
143 int elevel,
char **err_msg);
145 char **err_msg,
int elevel);
158 return c ==
' ' ||
c ==
'\t' ||
c ==
'\r';
200 bool *initial_quote,
bool *terminating_comma,
201 int elevel,
char **err_msg)
204 char *start_buf =
buf;
205 char *end_buf =
buf + (bufsz - 1);
206 bool in_quote =
false;
207 bool was_quote =
false;
208 bool saw_quote =
false;
210 Assert(end_buf > start_buf);
212 *initial_quote =
false;
213 *terminating_comma =
false;
227 if (
c ==
'#' && !in_quote)
229 while ((
c = (*(*
lineptr)++)) !=
'\0')
238 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
239 errmsg(
"authentication file token too long, skipping: \"%s\"",
241 *err_msg =
"authentication file token too long";
243 while ((
c = (*(*
lineptr)++)) !=
'\0')
251 if (
c ==
',' && !in_quote)
253 *terminating_comma =
true;
257 if (
c !=
'"' || was_quote)
261 if (in_quote &&
c ==
'"')
262 was_quote = !was_quote;
268 in_quote = !in_quote;
270 if (
buf == start_buf)
271 *initial_quote =
true;
285 return (saw_quote ||
buf > start_buf);
297 toklen = strlen(
token);
301 authtoken->
quoted = quoted;
302 authtoken->
regex = NULL;
328 foreach(cell, line->
roles)
361 char **err_msg,
int elevel)
369 if (
token->string[0] !=
'/')
375 wstr, strlen(
token->string + 1));
385 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
386 errmsg(
"invalid regular expression \"%s\": %s",
387 token->string + 1, errstr),
388 errcontext(
"line %d of configuration file \"%s\"",
391 *err_msg =
psprintf(
"invalid regular expression \"%s\": %s",
392 token->string + 1, errstr);
417 r =
pg_regexec(
token->regex, wmatchstr, wmatchlen, 0, NULL, nmatch, pmatch, 0);
439 int elevel,
int depth,
char **err_msg)
449 &initial_quote, &trailing_comma,
454 if (!initial_quote &&
buf[0] ==
'@' &&
buf[1] !=
'\0')
456 elevel, depth + 1, err_msg);
469 }
while (trailing_comma && (*err_msg == NULL));
495 const char *inc_filename,
510 if (errno == ENOENT && missing_ok)
513 (
errmsg(
"skipping missing authentication file \"%s\"",
550 const char *outer_filename,
551 const char *inc_filename,
564 if (inc_file == NULL)
584 foreach(inc_line, inc_lines)
596 foreach(inc_field, tok_line->
fields)
601 foreach(inc_token, inc_tokens)
665 errmsg(
"could not open file \"%s\": maximum nesting depth exceeded",
668 *err_msg =
psprintf(
"could not open file \"%s\": maximum nesting depth exceeded",
676 int save_errno = errno;
680 errmsg(
"could not open file \"%s\": %m",
683 *err_msg =
psprintf(
"could not open file \"%s\": %s",
717 errcontext(
"line %d of configuration file \"%s\"",
743 int elevel,
int depth)
755 callback_arg.
linenum = line_number;
758 tokenerrcontext.
arg = (
void *) &callback_arg;
767 "tokenize_auth_file",
776 while (!feof(file) && !ferror(file))
782 char *err_msg = NULL;
783 int last_backslash_buflen = 0;
784 int continuations = 0;
799 if (
buf.len > last_backslash_buflen &&
800 buf.data[
buf.len - 1] ==
'\\')
803 buf.data[--
buf.len] =
'\0';
804 last_backslash_buflen =
buf.len;
816 int save_errno = errno;
821 err_msg =
psprintf(
"could not read file \"%s\": %s",
828 while (*
lineptr && err_msg == NULL)
833 elevel, depth, &err_msg);
835 if (current_field !=
NIL)
842 current_line =
lappend(current_line, current_field);
851 if (current_line ==
NIL && err_msg == NULL)
855 if (err_msg == NULL &&
list_length(current_line) == 2)
863 if (strcmp(first->
string,
"include") == 0)
866 elevel, depth + 1,
false, &err_msg);
877 else if (strcmp(first->
string,
"include_dir") == 0)
880 char *dir_name = second->
string;
885 &num_filenames, &err_msg);
894 for (
int i = 0;
i < num_filenames;
i++)
897 elevel, depth + 1,
false, &err_msg);
908 for (
int i = 0;
i < num_filenames;
i++)
916 if (err_buf.
len == 0)
920 err_msg = err_buf.
data;
923 else if (strcmp(first->
string,
"include_if_exists") == 0)
927 elevel, depth + 1,
true, &err_msg);
948 tok_line->
fields = current_line;
953 *tok_lines =
lappend(*tok_lines, tok_line);
957 line_number += continuations + 1;
958 callback_arg.
linenum = line_number;
1009 foreach(cell, tokens)
1024 else if (case_insensitive)
1048 foreach(cell, tokens)
1064 if (strcmp(
dbname, role) == 0)
1089 return (
a->sin_addr.s_addr ==
b->sin_addr.s_addr);
1097 for (
i = 0;
i < 16;
i++)
1098 if (
a->sin6_addr.s6_addr[
i] !=
b->sin6_addr.s6_addr[
i])
1110 if (pattern[0] ==
'.')
1112 size_t plen = strlen(pattern);
1113 size_t hlen = strlen(actual_hostname);
1118 return (
pg_strcasecmp(pattern, actual_hostname + (hlen - plen)) == 0);
1130 struct addrinfo *gai_result,
1136 if (
port->remote_hostname_resolv < 0)
1140 if (!
port->remote_hostname)
1142 char remote_hostname[NI_MAXHOST];
1145 remote_hostname,
sizeof(remote_hostname),
1151 port->remote_hostname_resolv = -2;
1152 port->remote_hostname_errcode = ret;
1164 if (
port->remote_hostname_resolv == +1)
1168 ret = getaddrinfo(
port->remote_hostname, NULL, NULL, &gai_result);
1172 port->remote_hostname_resolv = -2;
1173 port->remote_hostname_errcode = ret;
1178 for (gai = gai_result; gai; gai = gai->ai_next)
1180 if (gai->ai_addr->sa_family ==
port->raddr.addr.ss_family)
1182 if (gai->ai_addr->sa_family == AF_INET)
1184 if (
ipv4eq((
struct sockaddr_in *) gai->ai_addr,
1185 (
struct sockaddr_in *) &
port->raddr.addr))
1191 else if (gai->ai_addr->sa_family == AF_INET6)
1193 if (
ipv6eq((
struct sockaddr_in6 *) gai->ai_addr,
1194 (
struct sockaddr_in6 *) &
port->raddr.addr))
1204 freeaddrinfo(gai_result);
1207 elog(
DEBUG2,
"pg_hba.conf host name \"%s\" rejected because address resolution did not return a match with IP address of client",
1210 port->remote_hostname_resolv = found ? +1 : -1;
1221 if (raddr->
addr.ss_family == addr->sa_family &&
1223 (
struct sockaddr_storage *) addr,
1224 (
struct sockaddr_storage *) mask))
1237 struct sockaddr_storage mask;
1272 (
errmsg(
"error enumerating network interfaces: %m")));
1294 #define INVALID_AUTH_OPTION(optname, validmethods) \
1297 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1299 errmsg("authentication option \"%s\" is only valid for authentication methods %s", \
1300 optname, _(validmethods)), \
1301 errcontext("line %d of configuration file \"%s\"", \
1302 line_num, file_name))); \
1303 *err_msg = psprintf("authentication option \"%s\" is only valid for authentication methods %s", \
1304 optname, validmethods); \
1308 #define REQUIRE_AUTH_OPTION(methodval, optname, validmethods) \
1310 if (hbaline->auth_method != methodval) \
1311 INVALID_AUTH_OPTION(optname, validmethods); \
1314 #define MANDATORY_AUTH_ARG(argvar, argname, authname) \
1316 if (argvar == NULL) { \
1318 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1319 errmsg("authentication method \"%s\" requires argument \"%s\" to be set", \
1320 authname, argname), \
1321 errcontext("line %d of configuration file \"%s\"", \
1322 line_num, file_name))); \
1323 *err_msg = psprintf("authentication method \"%s\" requires argument \"%s\" to be set", \
1324 authname, argname); \
1338 #define IDENT_FIELD_ABSENT(field) \
1342 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1343 errmsg("missing entry at end of line"), \
1344 errcontext("line %d of configuration file \"%s\"", \
1345 line_num, file_name))); \
1346 *err_msg = pstrdup("missing entry at end of line"); \
1351 #define IDENT_MULTI_VALUE(tokens) \
1353 if (tokens->length > 1) { \
1355 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1356 errmsg("multiple values in ident field"), \
1357 errcontext("line %d of configuration file \"%s\"", \
1358 line_num, file_name))); \
1359 *err_msg = pstrdup("multiple values in ident field"); \
1382 char **err_msg = &tok_line->
err_msg;
1384 struct addrinfo *gai_result;
1385 struct addrinfo hints;
1407 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1408 errmsg(
"multiple values specified for connection type"),
1409 errhint(
"Specify exactly one connection type per line."),
1410 errcontext(
"line %d of configuration file \"%s\"",
1411 line_num, file_name)));
1412 *err_msg =
"multiple values specified for connection type";
1416 if (strcmp(
token->string,
"local") == 0)
1420 else if (strcmp(
token->string,
"host") == 0 ||
1421 strcmp(
token->string,
"hostssl") == 0 ||
1422 strcmp(
token->string,
"hostnossl") == 0 ||
1423 strcmp(
token->string,
"hostgssenc") == 0 ||
1424 strcmp(
token->string,
"hostnogssenc") == 0)
1427 if (
token->string[4] ==
's')
1435 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1436 errmsg(
"hostssl record cannot match because SSL is disabled"),
1437 errhint(
"Set ssl = on in postgresql.conf."),
1438 errcontext(
"line %d of configuration file \"%s\"",
1439 line_num, file_name)));
1440 *err_msg =
"hostssl record cannot match because SSL is disabled";
1444 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1445 errmsg(
"hostssl record cannot match because SSL is not supported by this build"),
1446 errcontext(
"line %d of configuration file \"%s\"",
1447 line_num, file_name)));
1448 *err_msg =
"hostssl record cannot match because SSL is not supported by this build";
1451 else if (
token->string[4] ==
'g')
1456 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1457 errmsg(
"hostgssenc record cannot match because GSSAPI is not supported by this build"),
1458 errcontext(
"line %d of configuration file \"%s\"",
1459 line_num, file_name)));
1460 *err_msg =
"hostgssenc record cannot match because GSSAPI is not supported by this build";
1463 else if (
token->string[4] ==
'n' &&
token->string[6] ==
's')
1465 else if (
token->string[4] ==
'n' &&
token->string[6] ==
'g')
1476 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1477 errmsg(
"invalid connection type \"%s\"",
1479 errcontext(
"line %d of configuration file \"%s\"",
1480 line_num, file_name)));
1481 *err_msg =
psprintf(
"invalid connection type \"%s\"",
token->string);
1490 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1491 errmsg(
"end-of-line before database specification"),
1492 errcontext(
"line %d of configuration file \"%s\"",
1493 line_num, file_name)));
1494 *err_msg =
"end-of-line before database specification";
1499 foreach(tokencell, tokens)
1515 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1516 errmsg(
"end-of-line before role specification"),
1517 errcontext(
"line %d of configuration file \"%s\"",
1518 line_num, file_name)));
1519 *err_msg =
"end-of-line before role specification";
1524 foreach(tokencell, tokens)
1542 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1543 errmsg(
"end-of-line before IP address specification"),
1544 errcontext(
"line %d of configuration file \"%s\"",
1545 line_num, file_name)));
1546 *err_msg =
"end-of-line before IP address specification";
1553 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1554 errmsg(
"multiple values specified for host address"),
1555 errhint(
"Specify one address range per line."),
1556 errcontext(
"line %d of configuration file \"%s\"",
1557 line_num, file_name)));
1558 *err_msg =
"multiple values specified for host address";
1586 cidr_slash = strchr(
str,
'/');
1591 hints.ai_flags = AI_NUMERICHOST;
1592 hints.ai_family = AF_UNSPEC;
1593 hints.ai_socktype = 0;
1594 hints.ai_protocol = 0;
1595 hints.ai_addrlen = 0;
1596 hints.ai_canonname = NULL;
1597 hints.ai_addr = NULL;
1598 hints.ai_next = NULL;
1601 if (ret == 0 && gai_result)
1603 memcpy(&parsedline->
addr, gai_result->ai_addr,
1604 gai_result->ai_addrlen);
1605 parsedline->
addrlen = gai_result->ai_addrlen;
1607 else if (ret == EAI_NONAME)
1612 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1613 errmsg(
"invalid IP address \"%s\": %s",
1614 str, gai_strerror(ret)),
1615 errcontext(
"line %d of configuration file \"%s\"",
1616 line_num, file_name)));
1617 *err_msg =
psprintf(
"invalid IP address \"%s\": %s",
1618 str, gai_strerror(ret));
1632 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1633 errmsg(
"specifying both host name and CIDR mask is invalid: \"%s\"",
1635 errcontext(
"line %d of configuration file \"%s\"",
1636 line_num, file_name)));
1637 *err_msg =
psprintf(
"specifying both host name and CIDR mask is invalid: \"%s\"",
1643 parsedline->
addr.ss_family) < 0)
1646 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1647 errmsg(
"invalid CIDR mask in address \"%s\"",
1649 errcontext(
"line %d of configuration file \"%s\"",
1650 line_num, file_name)));
1651 *err_msg =
psprintf(
"invalid CIDR mask in address \"%s\"",
1666 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1667 errmsg(
"end-of-line before netmask specification"),
1668 errhint(
"Specify an address range in CIDR notation, or provide a separate netmask."),
1669 errcontext(
"line %d of configuration file \"%s\"",
1670 line_num, file_name)));
1671 *err_msg =
"end-of-line before netmask specification";
1678 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1679 errmsg(
"multiple values specified for netmask"),
1680 errcontext(
"line %d of configuration file \"%s\"",
1681 line_num, file_name)));
1682 *err_msg =
"multiple values specified for netmask";
1688 &hints, &gai_result);
1689 if (ret || !gai_result)
1692 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1693 errmsg(
"invalid IP mask \"%s\": %s",
1694 token->string, gai_strerror(ret)),
1695 errcontext(
"line %d of configuration file \"%s\"",
1696 line_num, file_name)));
1697 *err_msg =
psprintf(
"invalid IP mask \"%s\": %s",
1698 token->string, gai_strerror(ret));
1704 memcpy(&parsedline->
mask, gai_result->ai_addr,
1705 gai_result->ai_addrlen);
1706 parsedline->
masklen = gai_result->ai_addrlen;
1709 if (parsedline->
addr.ss_family != parsedline->
mask.ss_family)
1712 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1713 errmsg(
"IP address and mask do not match"),
1714 errcontext(
"line %d of configuration file \"%s\"",
1715 line_num, file_name)));
1716 *err_msg =
"IP address and mask do not match";
1728 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1729 errmsg(
"end-of-line before authentication method"),
1730 errcontext(
"line %d of configuration file \"%s\"",
1731 line_num, file_name)));
1732 *err_msg =
"end-of-line before authentication method";
1739 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1740 errmsg(
"multiple values specified for authentication type"),
1741 errhint(
"Specify exactly one authentication type per line."),
1742 errcontext(
"line %d of configuration file \"%s\"",
1743 line_num, file_name)));
1744 *err_msg =
"multiple values specified for authentication type";
1750 if (strcmp(
token->string,
"trust") == 0)
1752 else if (strcmp(
token->string,
"ident") == 0)
1754 else if (strcmp(
token->string,
"peer") == 0)
1756 else if (strcmp(
token->string,
"password") == 0)
1758 else if (strcmp(
token->string,
"gss") == 0)
1764 else if (strcmp(
token->string,
"sspi") == 0)
1770 else if (strcmp(
token->string,
"reject") == 0)
1772 else if (strcmp(
token->string,
"md5") == 0)
1777 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1778 errmsg(
"MD5 authentication is not supported when \"db_user_namespace\" is enabled"),
1779 errcontext(
"line %d of configuration file \"%s\"",
1780 line_num, file_name)));
1781 *err_msg =
"MD5 authentication is not supported when \"db_user_namespace\" is enabled";
1786 else if (strcmp(
token->string,
"scram-sha-256") == 0)
1788 else if (strcmp(
token->string,
"pam") == 0)
1794 else if (strcmp(
token->string,
"bsd") == 0)
1800 else if (strcmp(
token->string,
"ldap") == 0)
1806 else if (strcmp(
token->string,
"cert") == 0)
1812 else if (strcmp(
token->string,
"radius") == 0)
1817 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1818 errmsg(
"invalid authentication method \"%s\"",
1820 errcontext(
"line %d of configuration file \"%s\"",
1821 line_num, file_name)));
1822 *err_msg =
psprintf(
"invalid authentication method \"%s\"",
1830 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1831 errmsg(
"invalid authentication method \"%s\": not supported by this build",
1833 errcontext(
"line %d of configuration file \"%s\"",
1834 line_num, file_name)));
1835 *err_msg =
psprintf(
"invalid authentication method \"%s\": not supported by this build",
1853 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1854 errmsg(
"gssapi authentication is not supported on local sockets"),
1855 errcontext(
"line %d of configuration file \"%s\"",
1856 line_num, file_name)));
1857 *err_msg =
"gssapi authentication is not supported on local sockets";
1865 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1866 errmsg(
"peer authentication is only supported on local sockets"),
1867 errcontext(
"line %d of configuration file \"%s\"",
1868 line_num, file_name)));
1869 *err_msg =
"peer authentication is only supported on local sockets";
1883 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1884 errmsg(
"cert authentication is only supported on hostssl connections"),
1885 errcontext(
"line %d of configuration file \"%s\"",
1886 line_num, file_name)));
1887 *err_msg =
"cert authentication is only supported on hostssl connections";
1916 while ((field =
lnext(tok_line->
fields, field)) != NULL)
1919 foreach(tokencell, tokens)
1933 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1934 errmsg(
"authentication option not in name=value format: %s",
token->string),
1935 errcontext(
"line %d of configuration file \"%s\"",
1936 line_num, file_name)));
1937 *err_msg =
psprintf(
"authentication option not in name=value format: %s",
1956 #ifndef HAVE_LDAP_INITIALIZE
1977 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1978 errmsg(
"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix"),
1979 errcontext(
"line %d of configuration file \"%s\"",
1980 line_num, file_name)));
1981 *err_msg =
"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix";
1988 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1989 errmsg(
"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set"),
1990 errcontext(
"line %d of configuration file \"%s\"",
1991 line_num, file_name)));
1992 *err_msg =
"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set";
2004 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2005 errmsg(
"cannot use ldapsearchattribute together with ldapsearchfilter"),
2006 errcontext(
"line %d of configuration file \"%s\"",
2007 line_num, file_name)));
2008 *err_msg =
"cannot use ldapsearchattribute together with ldapsearchfilter";
2021 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2022 errmsg(
"list of RADIUS servers cannot be empty"),
2023 errcontext(
"line %d of configuration file \"%s\"",
2024 line_num, file_name)));
2025 *err_msg =
"list of RADIUS servers cannot be empty";
2032 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2033 errmsg(
"list of RADIUS secrets cannot be empty"),
2034 errcontext(
"line %d of configuration file \"%s\"",
2035 line_num, file_name)));
2036 *err_msg =
"list of RADIUS secrets cannot be empty";
2049 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2050 errmsg(
"the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2053 errcontext(
"line %d of configuration file \"%s\"",
2054 line_num, file_name)));
2055 *err_msg =
psprintf(
"the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2065 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2066 errmsg(
"the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2069 errcontext(
"line %d of configuration file \"%s\"",
2070 line_num, file_name)));
2071 *err_msg =
psprintf(
"the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2081 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2082 errmsg(
"the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2085 errcontext(
"line %d of configuration file \"%s\"",
2086 line_num, file_name)));
2087 *err_msg =
psprintf(
"the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)",
2118 int elevel,
char **err_msg)
2124 hbaline->
ldapscope = LDAP_SCOPE_SUBTREE;
2127 if (strcmp(
name,
"map") == 0)
2137 else if (strcmp(
name,
"clientcert") == 0)
2142 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2143 errmsg(
"clientcert can only be configured for \"hostssl\" rows"),
2144 errcontext(
"line %d of configuration file \"%s\"",
2145 line_num, file_name)));
2146 *err_msg =
"clientcert can only be configured for \"hostssl\" rows";
2150 if (strcmp(
val,
"verify-full") == 0)
2154 else if (strcmp(
val,
"verify-ca") == 0)
2159 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2160 errmsg(
"clientcert only accepts \"verify-full\" when using \"cert\" authentication"),
2161 errcontext(
"line %d of configuration file \"%s\"",
2162 line_num, file_name)));
2163 *err_msg =
"clientcert can only be set to \"verify-full\" when using \"cert\" authentication";
2172 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2173 errmsg(
"invalid value for clientcert: \"%s\"",
val),
2174 errcontext(
"line %d of configuration file \"%s\"",
2175 line_num, file_name)));
2179 else if (strcmp(
name,
"clientname") == 0)
2184 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2185 errmsg(
"clientname can only be configured for \"hostssl\" rows"),
2186 errcontext(
"line %d of configuration file \"%s\"",
2187 line_num, file_name)));
2188 *err_msg =
"clientname can only be configured for \"hostssl\" rows";
2192 if (strcmp(
val,
"CN") == 0)
2196 else if (strcmp(
val,
"DN") == 0)
2203 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2204 errmsg(
"invalid value for clientname: \"%s\"",
val),
2205 errcontext(
"line %d of configuration file \"%s\"",
2206 line_num, file_name)));
2210 else if (strcmp(
name,
"pamservice") == 0)
2215 else if (strcmp(
name,
"pam_use_hostname") == 0)
2218 if (strcmp(
val,
"1") == 0)
2223 else if (strcmp(
name,
"ldapurl") == 0)
2225 #ifdef LDAP_API_FEATURE_X_OPENLDAP
2226 LDAPURLDesc *urldata;
2231 #ifdef LDAP_API_FEATURE_X_OPENLDAP
2232 rc = ldap_url_parse(
val, &urldata);
2233 if (rc != LDAP_SUCCESS)
2236 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2237 errmsg(
"could not parse LDAP URL \"%s\": %s",
val, ldap_err2string(rc))));
2238 *err_msg =
psprintf(
"could not parse LDAP URL \"%s\": %s",
2239 val, ldap_err2string(rc));
2243 if (strcmp(urldata->lud_scheme,
"ldap") != 0 &&
2244 strcmp(urldata->lud_scheme,
"ldaps") != 0)
2247 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2248 errmsg(
"unsupported LDAP URL scheme: %s", urldata->lud_scheme)));
2249 *err_msg =
psprintf(
"unsupported LDAP URL scheme: %s",
2250 urldata->lud_scheme);
2251 ldap_free_urldesc(urldata);
2255 if (urldata->lud_scheme)
2257 if (urldata->lud_host)
2259 hbaline->
ldapport = urldata->lud_port;
2260 if (urldata->lud_dn)
2263 if (urldata->lud_attrs)
2265 hbaline->
ldapscope = urldata->lud_scope;
2266 if (urldata->lud_filter)
2268 ldap_free_urldesc(urldata);
2271 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2272 errmsg(
"LDAP URLs not supported on this platform")));
2273 *err_msg =
"LDAP URLs not supported on this platform";
2276 else if (strcmp(
name,
"ldaptls") == 0)
2279 if (strcmp(
val,
"1") == 0)
2284 else if (strcmp(
name,
"ldapscheme") == 0)
2287 if (strcmp(
val,
"ldap") != 0 && strcmp(
val,
"ldaps") != 0)
2289 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2290 errmsg(
"invalid ldapscheme value: \"%s\"",
val),
2291 errcontext(
"line %d of configuration file \"%s\"",
2292 line_num, file_name)));
2295 else if (strcmp(
name,
"ldapserver") == 0)
2300 else if (strcmp(
name,
"ldapport") == 0)
2307 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2308 errmsg(
"invalid LDAP port number: \"%s\"",
val),
2309 errcontext(
"line %d of configuration file \"%s\"",
2310 line_num, file_name)));
2311 *err_msg =
psprintf(
"invalid LDAP port number: \"%s\"",
val);
2315 else if (strcmp(
name,
"ldapbinddn") == 0)
2320 else if (strcmp(
name,
"ldapbindpasswd") == 0)
2325 else if (strcmp(
name,
"ldapsearchattribute") == 0)
2330 else if (strcmp(
name,
"ldapsearchfilter") == 0)
2335 else if (strcmp(
name,
"ldapbasedn") == 0)
2340 else if (strcmp(
name,
"ldapprefix") == 0)
2345 else if (strcmp(
name,
"ldapsuffix") == 0)
2350 else if (strcmp(
name,
"krb_realm") == 0)
2357 else if (strcmp(
name,
"include_realm") == 0)
2362 if (strcmp(
val,
"1") == 0)
2367 else if (strcmp(
name,
"compat_realm") == 0)
2371 if (strcmp(
val,
"1") == 0)
2376 else if (strcmp(
name,
"upn_username") == 0)
2380 if (strcmp(
val,
"1") == 0)
2385 else if (strcmp(
name,
"radiusservers") == 0)
2387 struct addrinfo *gai_result;
2388 struct addrinfo hints;
2390 List *parsed_servers;
2400 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2401 errmsg(
"could not parse RADIUS server list \"%s\"",
2403 errcontext(
"line %d of configuration file \"%s\"",
2404 line_num, file_name)));
2409 foreach(l, parsed_servers)
2411 MemSet(&hints, 0,
sizeof(hints));
2412 hints.ai_socktype = SOCK_DGRAM;
2413 hints.ai_family = AF_UNSPEC;
2416 if (ret || !gai_result)
2419 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2420 errmsg(
"could not translate RADIUS server name \"%s\" to address: %s",
2421 (
char *)
lfirst(l), gai_strerror(ret)),
2422 errcontext(
"line %d of configuration file \"%s\"",
2423 line_num, file_name)));
2437 else if (strcmp(
name,
"radiusports") == 0)
2448 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2449 errmsg(
"could not parse RADIUS port list \"%s\"",
2451 errcontext(
"line %d of configuration file \"%s\"",
2452 line_num, file_name)));
2453 *err_msg =
psprintf(
"invalid RADIUS port number: \"%s\"",
val);
2457 foreach(l, parsed_ports)
2459 if (atoi(
lfirst(l)) == 0)
2462 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2463 errmsg(
"invalid RADIUS port number: \"%s\"",
val),
2464 errcontext(
"line %d of configuration file \"%s\"",
2465 line_num, file_name)));
2473 else if (strcmp(
name,
"radiussecrets") == 0)
2475 List *parsed_secrets;
2484 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2485 errmsg(
"could not parse RADIUS secret list \"%s\"",
2487 errcontext(
"line %d of configuration file \"%s\"",
2488 line_num, file_name)));
2495 else if (strcmp(
name,
"radiusidentifiers") == 0)
2497 List *parsed_identifiers;
2506 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2507 errmsg(
"could not parse RADIUS identifiers list \"%s\"",
2509 errcontext(
"line %d of configuration file \"%s\"",
2510 line_num, file_name)));
2520 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2521 errmsg(
"unrecognized authentication option name: \"%s\"",
2523 errcontext(
"line %d of configuration file \"%s\"",
2524 line_num, file_name)));
2525 *err_msg =
psprintf(
"unrecognized authentication option name: \"%s\"",
2553 if (
port->raddr.addr.ss_family != AF_UNIX)
2558 if (
port->raddr.addr.ss_family == AF_UNIX)
2562 if (
port->ssl_in_use)
2580 else if (!(
port->gss &&
port->gss->enc) &&
2601 (
struct sockaddr *) &hba->
addr,
2602 (
struct sockaddr *) &hba->
mask))
2673 "hba parser context",
2676 foreach(line, hba_lines)
2682 if (tok_line->
err_msg != NULL)
2709 if (ok && new_parsed_lines ==
NIL)
2712 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
2713 errmsg(
"configuration file \"%s\" contains no entries",
2729 foreach(line, new_parsed_lines)
2777 char **err_msg = &tok_line->
err_msg;
2843 bool case_insensitive,
bool *found_p,
bool *error_p)
2850 if (strcmp(identLine->
usermap, usermap_name) != 0)
2869 bool created_temporary_token =
false;
2881 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
2882 errmsg(
"regular expression match for \"%s\" failed: %s",
2898 char *expanded_pg_user;
2902 if (matches[1].rm_so < 0)
2905 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
2906 errmsg(
"regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"",
2918 memcpy(expanded_pg_user, identLine->
pg_user->
string, offset);
2919 memcpy(expanded_pg_user + offset,
2921 matches[1].rm_eo - matches[1].rm_so);
2922 strcat(expanded_pg_user, ofs + 2);
2930 created_temporary_token =
true;
2931 pfree(expanded_pg_user);
2935 expanded_pg_user_token = identLine->
pg_user;
2943 if (created_temporary_token)
2954 if (case_insensitive)
2989 const char *pg_user,
2991 bool case_insensitive)
2993 bool found_entry =
false,
2996 if (usermap_name == NULL || usermap_name[0] ==
'\0')
2998 if (case_insensitive)
3009 (
errmsg(
"provided user name (%s) and authenticated user name (%s) do not match",
3021 &found_entry, &
error);
3022 if (found_entry ||
error)
3026 if (!found_entry && !
error)
3029 (
errmsg(
"no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"",
3068 "ident parser context",
3071 foreach(line_cell, ident_lines)
3076 if (tok_line->
err_msg != NULL)
3109 foreach(parsed_line_cell, new_parsed_lines)
bool is_member_of_role_nosuper(Oid member, Oid role)
Oid get_role_oid(const char *rolname, bool missing_ok)
#define MemSet(start, val, len)
#define OidIsValid(objectId)
char * AbsoluteConfigLocation(const char *location, const char *calling_file)
char ** GetConfFilesInDir(const char *includedir, const char *calling_file, int elevel, int *num_filenames, char **err_msg)
#define CONF_FILE_MAX_DEPTH
#define CONF_FILE_START_DEPTH
elog(ERROR, "%s: %s", p2, msg)
int errcode_for_file_access(void)
ErrorContextCallback * error_context_stack
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
FILE * AllocateFile(const char *name, const char *mode)
IdentLine * parse_ident_line(TokenizedAuthLine *tok_line, int elevel)
bool pg_isblank(const char c)
FILE * open_auth_file(const char *filename, int elevel, int depth, char **err_msg)
#define MANDATORY_AUTH_ARG(argvar, argname, authname)
static bool is_member(Oid userid, const char *role)
static bool check_role(const char *role, Oid roleid, List *tokens, bool case_insensitive)
static bool hostname_match(const char *pattern, const char *actual_hostname)
StaticAssertDecl(lengthof(UserAuthName)==USER_AUTH_LAST+1, "UserAuthName[] must match the UserAuth enum")
static List * next_field_expand(const char *filename, char **lineptr, int elevel, int depth, char **err_msg)
static bool check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask)
#define token_is_member_check(t)
#define IDENT_FIELD_ABSENT(field)
#define token_is_keyword(t, k)
static bool ipv4eq(struct sockaddr_in *a, struct sockaddr_in *b)
static MemoryContext parsed_ident_context
#define token_matches_insensitive(t, k)
static void free_hba_line(HbaLine *line)
struct check_network_data check_network_data
static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg)
static bool check_same_host_or_net(SockAddr *raddr, IPCompareMethod method)
static int regcomp_auth_token(AuthToken *token, char *filename, int line_num, char **err_msg, int elevel)
static bool next_token(char **lineptr, char *buf, int bufsz, bool *initial_quote, bool *terminating_comma, int elevel, char **err_msg)
static MemoryContext tokenize_context
static int regexec_auth_token(const char *match, AuthToken *token, size_t nmatch, regmatch_t pmatch[])
static void tokenize_include_file(const char *outer_filename, const char *inc_filename, List **tok_lines, int elevel, int depth, bool missing_ok, char **err_msg)
static bool check_hostname(hbaPort *port, const char *hostname)
static void tokenize_error_callback(void *arg)
static void check_hba(hbaPort *port)
static void check_network_callback(struct sockaddr *addr, struct sockaddr *netmask, void *cb_data)
#define token_has_regexp(t)
const char * hba_authname(UserAuth auth_method)
static MemoryContext parsed_hba_context
static AuthToken * copy_auth_token(AuthToken *in)
#define IDENT_MULTI_VALUE(tokens)
void hba_getauthmethod(hbaPort *port)
int check_usermap(const char *usermap_name, const char *pg_user, const char *system_user, bool case_insensitive)
void free_auth_file(FILE *file, int depth)
static bool ipv6eq(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
static List * tokenize_expand_file(List *tokens, const char *outer_filename, const char *inc_filename, int elevel, int depth, char **err_msg)
static void free_auth_token(AuthToken *token)
static List * parsed_ident_lines
static const char *const UserAuthName[]
#define token_matches(t, k)
HbaLine * parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
static List * parsed_hba_lines
#define INVALID_AUTH_OPTION(optname, validmethods)
static AuthToken * make_auth_token(const char *token, bool quoted)
void tokenize_auth_file(const char *filename, FILE *file, List **tok_lines, int elevel, int depth)
static void check_ident_usermap(IdentLine *identLine, const char *usermap_name, const char *pg_user, const char *system_user, bool case_insensitive, bool *found_p, bool *error_p)
static bool check_db(const char *dbname, const char *role, Oid roleid, List *tokens)
#define REQUIRE_AUTH_OPTION(methodval, optname, validmethods)
int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
int pg_range_sockaddr(const struct sockaddr_storage *addr, const struct sockaddr_storage *netaddr, const struct sockaddr_storage *netmask)
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')
List * lappend(List *list, void *datum)
void list_free(List *list)
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
MemoryContext PostmasterContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_START_SMALL_SIZES
#define ALLOCSET_SMALL_SIZES
Datum system_user(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool pg_get_line_append(FILE *stream, StringInfo buf, PromptInterruptContext *prompt_ctx)
static int list_length(const List *l)
#define linitial_node(type, l)
#define lsecond_node(type, l)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
int pg_strcasecmp(const char *s1, const char *s2)
char * psprintf(const char *fmt,...)
int pg_regcomp(regex_t *re, const chr *string, size_t len, int flags, Oid collation)
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
int pg_regexec(regex_t *re, const chr *string, size_t len, size_t search_start, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags)
void pg_regfree(regex_t *re)
int pg_strip_crlf(char *str)
void resetStringInfo(StringInfo str)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
struct ErrorContextCallback * previous
void(* callback)(void *arg)
struct sockaddr_storage mask
ClientCertName clientcertname
ClientCertMode clientcert
char * ldapsearchattribute
struct sockaddr_storage addr
IPCompareMethod ip_cmp_method
char * radiusidentifiers_s
struct sockaddr_storage addr
bool SplitGUCList(char *rawstring, char separator, List **namelist)