69#define token_has_regexp(t) (t->regex != NULL)
70#define token_is_member_check(t) (!t->quoted && t->string[0] == '+')
71#define token_is_keyword(t, k) (!t->quoted && strcmp(t->string, k) == 0)
72#define token_matches(t, k) (strcmp(t->string, k) == 0)
73#define token_matches_insensitive(t,k) (pg_strcasecmp(t->string, k) == 0)
125 "UserAuthName[] must match the UserAuth enum");
130 int depth,
char **err_msg);
132 int elevel,
char **err_msg);
134 char **err_msg,
int elevel);
210 while ((
c = (*(*
lineptr)++)) !=
'\0')
300 char **err_msg,
int elevel)
308 if (
token->string[0] !=
'/')
325 errmsg(
"invalid regular expression \"%s\": %s",
327 errcontext(
"line %d of configuration file \"%s\"",
330 *err_msg =
psprintf(
"invalid regular expression \"%s\": %s",
378 int elevel,
int depth,
char **err_msg)
396 elevel, depth + 1, err_msg);
455 (
errmsg(
"skipping missing authentication file \"%s\"",
607 errmsg(
"could not open file \"%s\": maximum nesting depth exceeded",
610 *err_msg =
psprintf(
"could not open file \"%s\": maximum nesting depth exceeded",
622 errmsg(
"could not open file \"%s\": %m",
627 *err_msg =
psprintf(
"could not open file \"%s\": %m",
662 errcontext(
"line %d of configuration file \"%s\"",
688 int elevel,
int depth)
700 callback_arg.
linenum = line_number;
712 "tokenize_auth_file",
727 char *err_msg =
NULL;
745 buf.data[
buf.len - 1] ==
'\\')
748 buf.data[--
buf.len] =
'\0';
767 err_msg =
psprintf(
"could not read file \"%s\": %m",
779 elevel, depth, &err_msg);
812 elevel, depth + 1,
false, &err_msg);
843 elevel, depth + 1,
false, &err_msg);
869 else if (
strcmp(first->
string,
"include_if_exists") == 0)
873 elevel, depth + 1,
true, &err_msg);
904 callback_arg.
linenum = line_number;
1035 return (
a->sin_addr.s_addr ==
b->sin_addr.s_addr);
1043 for (
i = 0;
i < 16;
i++)
1044 if (
a->sin6_addr.s6_addr[
i] !=
b->sin6_addr.s6_addr[
i])
1056 if (pattern[0] ==
'.')
1058 size_t plen =
strlen(pattern);
1082 if (
port->remote_hostname_resolv < 0)
1086 if (!
port->remote_hostname)
1091 remote_hostname,
sizeof(remote_hostname),
1097 port->remote_hostname_resolv = -2;
1098 port->remote_hostname_errcode = ret;
1110 if (
port->remote_hostname_resolv == +1)
1118 port->remote_hostname_resolv = -2;
1119 port->remote_hostname_errcode = ret;
1126 if (
gai->ai_addr->sa_family ==
port->raddr.addr.ss_family)
1153 elog(
DEBUG2,
"pg_hba.conf host name \"%s\" rejected because address resolution did not return a match with IP address of client",
1156 port->remote_hostname_resolv = found ? +1 : -1;
1167 if (raddr->
addr.ss_family == addr->sa_family &&
1218 (
errmsg(
"error enumerating network interfaces: %m")));
1240#define INVALID_AUTH_OPTION(optname, validmethods) \
1243 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1245 errmsg("authentication option \"%s\" is only valid for authentication methods %s", \
1246 optname, _(validmethods)), \
1247 errcontext("line %d of configuration file \"%s\"", \
1248 line_num, file_name))); \
1249 *err_msg = psprintf("authentication option \"%s\" is only valid for authentication methods %s", \
1250 optname, validmethods); \
1254#define REQUIRE_AUTH_OPTION(methodval, optname, validmethods) \
1256 if (hbaline->auth_method != methodval) \
1257 INVALID_AUTH_OPTION(optname, validmethods); \
1260#define MANDATORY_AUTH_ARG(argvar, argname, authname) \
1262 if (argvar == NULL) { \
1264 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1265 errmsg("authentication method \"%s\" requires argument \"%s\" to be set", \
1266 authname, argname), \
1267 errcontext("line %d of configuration file \"%s\"", \
1268 line_num, file_name))); \
1269 *err_msg = psprintf("authentication method \"%s\" requires argument \"%s\" to be set", \
1270 authname, argname); \
1284#define IDENT_FIELD_ABSENT(field) \
1288 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1289 errmsg("missing entry at end of line"), \
1290 errcontext("line %d of configuration file \"%s\"", \
1291 line_num, file_name))); \
1292 *err_msg = pstrdup("missing entry at end of line"); \
1297#define IDENT_MULTI_VALUE(tokens) \
1299 if (tokens->length > 1) { \
1301 (errcode(ERRCODE_CONFIG_FILE_ERROR), \
1302 errmsg("multiple values in ident field"), \
1303 errcontext("line %d of configuration file \"%s\"", \
1304 line_num, file_name))); \
1305 *err_msg = pstrdup("multiple values in ident field"); \
1327 char *file_name =
tok_line->file_name;
1328 char **err_msg = &
tok_line->err_msg;
1354 errmsg(
"multiple values specified for connection type"),
1355 errhint(
"Specify exactly one connection type per line."),
1356 errcontext(
"line %d of configuration file \"%s\"",
1357 line_num, file_name)));
1358 *err_msg =
"multiple values specified for connection type";
1373 if (
token->string[4] ==
's')
1382 errmsg(
"hostssl record cannot match because SSL is disabled"),
1383 errhint(
"Set \"ssl = on\" in postgresql.conf."),
1384 errcontext(
"line %d of configuration file \"%s\"",
1385 line_num, file_name)));
1386 *err_msg =
"hostssl record cannot match because SSL is disabled";
1391 errmsg(
"hostssl record cannot match because SSL is not supported by this build"),
1392 errcontext(
"line %d of configuration file \"%s\"",
1393 line_num, file_name)));
1394 *err_msg =
"hostssl record cannot match because SSL is not supported by this build";
1397 else if (
token->string[4] ==
'g')
1403 errmsg(
"hostgssenc record cannot match because GSSAPI is not supported by this build"),
1404 errcontext(
"line %d of configuration file \"%s\"",
1405 line_num, file_name)));
1406 *err_msg =
"hostgssenc record cannot match because GSSAPI is not supported by this build";
1409 else if (
token->string[4] ==
'n' &&
token->string[6] ==
's')
1411 else if (
token->string[4] ==
'n' &&
token->string[6] ==
'g')
1423 errmsg(
"invalid connection type \"%s\"",
1425 errcontext(
"line %d of configuration file \"%s\"",
1426 line_num, file_name)));
1427 *err_msg =
psprintf(
"invalid connection type \"%s\"",
token->string);
1437 errmsg(
"end-of-line before database specification"),
1438 errcontext(
"line %d of configuration file \"%s\"",
1439 line_num, file_name)));
1440 *err_msg =
"end-of-line before database specification";
1462 errmsg(
"end-of-line before role specification"),
1463 errcontext(
"line %d of configuration file \"%s\"",
1464 line_num, file_name)));
1465 *err_msg =
"end-of-line before role specification";
1489 errmsg(
"end-of-line before IP address specification"),
1490 errcontext(
"line %d of configuration file \"%s\"",
1491 line_num, file_name)));
1492 *err_msg =
"end-of-line before IP address specification";
1500 errmsg(
"multiple values specified for host address"),
1501 errhint(
"Specify one address range per line."),
1502 errcontext(
"line %d of configuration file \"%s\"",
1503 line_num, file_name)));
1504 *err_msg =
"multiple values specified for host address";
1539 hints.ai_socktype = 0;
1540 hints.ai_protocol = 0;
1541 hints.ai_addrlen = 0;
1559 errmsg(
"invalid IP address \"%s\": %s",
1561 errcontext(
"line %d of configuration file \"%s\"",
1562 line_num, file_name)));
1563 *err_msg =
psprintf(
"invalid IP address \"%s\": %s",
1579 errmsg(
"specifying both host name and CIDR mask is invalid: \"%s\"",
1581 errcontext(
"line %d of configuration file \"%s\"",
1582 line_num, file_name)));
1583 *err_msg =
psprintf(
"specifying both host name and CIDR mask is invalid: \"%s\"",
1593 errmsg(
"invalid CIDR mask in address \"%s\"",
1595 errcontext(
"line %d of configuration file \"%s\"",
1596 line_num, file_name)));
1597 *err_msg =
psprintf(
"invalid CIDR mask in address \"%s\"",
1613 errmsg(
"end-of-line before netmask specification"),
1614 errhint(
"Specify an address range in CIDR notation, or provide a separate netmask."),
1615 errcontext(
"line %d of configuration file \"%s\"",
1616 line_num, file_name)));
1617 *err_msg =
"end-of-line before netmask specification";
1625 errmsg(
"multiple values specified for netmask"),
1626 errcontext(
"line %d of configuration file \"%s\"",
1627 line_num, file_name)));
1628 *err_msg =
"multiple values specified for netmask";
1639 errmsg(
"invalid IP mask \"%s\": %s",
1641 errcontext(
"line %d of configuration file \"%s\"",
1642 line_num, file_name)));
1643 *err_msg =
psprintf(
"invalid IP mask \"%s\": %s",
1659 errmsg(
"IP address and mask do not match"),
1660 errcontext(
"line %d of configuration file \"%s\"",
1661 line_num, file_name)));
1662 *err_msg =
"IP address and mask do not match";
1675 errmsg(
"end-of-line before authentication method"),
1676 errcontext(
"line %d of configuration file \"%s\"",
1677 line_num, file_name)));
1678 *err_msg =
"end-of-line before authentication method";
1686 errmsg(
"multiple values specified for authentication type"),
1687 errhint(
"Specify exactly one authentication type per line."),
1688 errcontext(
"line %d of configuration file \"%s\"",
1689 line_num, file_name)));
1690 *err_msg =
"multiple values specified for authentication type";
1720 else if (
strcmp(
token->string,
"scram-sha-256") == 0)
1752 errmsg(
"invalid authentication method \"%s\"",
1754 errcontext(
"line %d of configuration file \"%s\"",
1755 line_num, file_name)));
1756 *err_msg =
psprintf(
"invalid authentication method \"%s\"",
1765 errmsg(
"invalid authentication method \"%s\": not supported by this build",
1767 errcontext(
"line %d of configuration file \"%s\"",
1768 line_num, file_name)));
1769 *err_msg =
psprintf(
"invalid authentication method \"%s\": not supported by this build",
1788 errmsg(
"gssapi authentication is not supported on local sockets"),
1789 errcontext(
"line %d of configuration file \"%s\"",
1790 line_num, file_name)));
1791 *err_msg =
"gssapi authentication is not supported on local sockets";
1800 errmsg(
"peer authentication is only supported on local sockets"),
1801 errcontext(
"line %d of configuration file \"%s\"",
1802 line_num, file_name)));
1803 *err_msg =
"peer authentication is only supported on local sockets";
1818 errmsg(
"cert authentication is only supported on hostssl connections"),
1819 errcontext(
"line %d of configuration file \"%s\"",
1820 line_num, file_name)));
1821 *err_msg =
"cert authentication is only supported on hostssl connections";
1868 errmsg(
"authentication option not in name=value format: %s",
token->string),
1869 errcontext(
"line %d of configuration file \"%s\"",
1870 line_num, file_name)));
1871 *err_msg =
psprintf(
"authentication option not in name=value format: %s",
1890#ifndef HAVE_LDAP_INITIALIZE
1912 errmsg(
"cannot mix options for simple bind and search+bind modes"),
1913 errcontext(
"line %d of configuration file \"%s\"",
1914 line_num, file_name)));
1915 *err_msg =
"cannot mix options for simple bind and search+bind modes";
1923 errmsg(
"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set"),
1924 errcontext(
"line %d of configuration file \"%s\"",
1925 line_num, file_name)));
1926 *err_msg =
"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set";
1939 errmsg(
"cannot use ldapsearchattribute together with ldapsearchfilter"),
1940 errcontext(
"line %d of configuration file \"%s\"",
1941 line_num, file_name)));
1942 *err_msg =
"cannot use ldapsearchattribute together with ldapsearchfilter";
1980 errmsg(
"%s cannot be used in combination with %s",
1981 "map",
"delegate_ident_mapping"),
1982 errcontext(
"line %d of configuration file \"%s\"",
1983 line_num, file_name));
1984 *err_msg =
"map cannot be used in combination with delegate_ident_mapping";
2001 int elevel,
char **err_msg)
2003 int line_num =
hbaline->linenumber;
2004 char *file_name =
hbaline->sourcefile;
2027 errmsg(
"clientcert can only be configured for \"hostssl\" rows"),
2028 errcontext(
"line %d of configuration file \"%s\"",
2029 line_num, file_name)));
2030 *err_msg =
"clientcert can only be configured for \"hostssl\" rows";
2044 errmsg(
"clientcert only accepts \"verify-full\" when using \"cert\" authentication"),
2045 errcontext(
"line %d of configuration file \"%s\"",
2046 line_num, file_name)));
2047 *err_msg =
"clientcert can only be set to \"verify-full\" when using \"cert\" authentication";
2057 errmsg(
"invalid value for clientcert: \"%s\"",
val),
2058 errcontext(
"line %d of configuration file \"%s\"",
2059 line_num, file_name)));
2069 errmsg(
"clientname can only be configured for \"hostssl\" rows"),
2070 errcontext(
"line %d of configuration file \"%s\"",
2071 line_num, file_name)));
2072 *err_msg =
"clientname can only be configured for \"hostssl\" rows";
2088 errmsg(
"invalid value for clientname: \"%s\"",
val),
2089 errcontext(
"line %d of configuration file \"%s\"",
2090 line_num, file_name)));
2099 else if (
strcmp(
name,
"pam_use_hostname") == 0)
2103 hbaline->pam_use_hostname =
true;
2105 hbaline->pam_use_hostname =
false;
2109#ifdef LDAP_API_FEATURE_X_OPENLDAP
2115#ifdef LDAP_API_FEATURE_X_OPENLDAP
2122 *err_msg =
psprintf(
"could not parse LDAP URL \"%s\": %s",
2132 errmsg(
"unsupported LDAP URL scheme: %s",
urldata->lud_scheme)));
2133 *err_msg =
psprintf(
"unsupported LDAP URL scheme: %s",
2156 errmsg(
"LDAP URLs not supported on this platform")));
2157 *err_msg =
"LDAP URLs not supported on this platform";
2174 errmsg(
"invalid ldapscheme value: \"%s\"",
val),
2175 errcontext(
"line %d of configuration file \"%s\"",
2176 line_num, file_name)));
2192 errmsg(
"invalid LDAP port number: \"%s\"",
val),
2193 errcontext(
"line %d of configuration file \"%s\"",
2194 line_num, file_name)));
2195 *err_msg =
psprintf(
"invalid LDAP port number: \"%s\"",
val);
2204 else if (
strcmp(
name,
"ldapbindpasswd") == 0)
2209 else if (
strcmp(
name,
"ldapsearchattribute") == 0)
2214 else if (
strcmp(
name,
"ldapsearchfilter") == 0)
2247 hbaline->include_realm =
true;
2249 hbaline->include_realm =
false;
2258 hbaline->compat_realm =
false;
2267 hbaline->upn_username =
false;
2286 const char *key =
name +
strlen(
"validator.");
2301 errmsg(
"invalid OAuth validator option name: \"%s\"",
name),
2302 errcontext(
"line %d of configuration file \"%s\"",
2303 line_num, file_name)));
2310 else if (
strcmp(
name,
"delegate_ident_mapping") == 0)
2314 hbaline->oauth_skip_usermap =
true;
2316 hbaline->oauth_skip_usermap =
false;
2322 errmsg(
"unrecognized authentication option name: \"%s\"",
2324 errcontext(
"line %d of configuration file \"%s\"",
2325 line_num, file_name)));
2326 *err_msg =
psprintf(
"unrecognized authentication option name: \"%s\"",
2363 if (
port->ssl_in_use)
2381 else if (!(
port->gss &&
port->gss->enc) &&
2474 "hba parser context",
2514 errmsg(
"configuration file \"%s\" contains no entries",
2561 char *file_name =
tok_line->file_name;
2562 char **err_msg = &
tok_line->err_msg;
2667 errmsg(
"regular expression match for \"%s\" failed: %s",
2694 errmsg(
"regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"",
2792 const char *pg_user,
2812 (
errmsg(
"provided user name (%s) and authenticated user name (%s) do not match",
2832 (
errmsg(
"no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"",
2870 "ident parser context",
bool is_member_of_role_nosuper(Oid member, Oid role)
Oid get_role_oid(const char *rolname, bool missing_ok)
bool check_oauth_validator(HbaLine *hbaline, int elevel, char **err_msg)
bool valid_oauth_hba_option_name(const char *name)
#define IS_HIGHBIT_SET(ch)
#define Assert(condition)
#define StaticAssertDecl(condition, errmessage)
#define OidIsValid(objectId)
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
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
int errcode_for_file_access(void)
ErrorContextCallback * error_context_stack
int errcode(int sqlerrcode)
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
FILE * AllocateFile(const char *name, const char *mode)
#define palloc0_object(type)
static AuthToken * make_auth_token(const char *token, bool quoted)
#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 check_hostname(Port *port, const char *hostname)
static bool pg_isblank(const char c)
HbaLine * parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
static bool hostname_match(const char *pattern, const char *actual_hostname)
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 List * next_field_expand(const char *filename, char **lineptr, int elevel, int depth, char **err_msg)
static MemoryContext parsed_ident_context
#define token_matches_insensitive(t, k)
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 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 void tokenize_error_callback(void *arg)
static void check_network_callback(struct sockaddr *addr, struct sockaddr *netmask, void *cb_data)
#define token_has_regexp(t)
static MemoryContext parsed_hba_context
static AuthToken * copy_auth_token(AuthToken *in)
#define IDENT_MULTI_VALUE(tokens)
IdentLine * parse_ident_line(TokenizedAuthLine *tok_line, int elevel)
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)
static bool next_token(char **lineptr, StringInfo buf, bool *initial_quote, bool *terminating_comma)
static List * parsed_hba_lines
#define INVALID_AUTH_OPTION(optname, validmethods)
void hba_getauthmethod(Port *port)
static void check_hba(Port *port)
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)
const char * hba_authname(UserAuth auth_method)
#define REQUIRE_AUTH_OPTION(methodval, optname, validmethods)
FILE * open_auth_file(const char *filename, int elevel, int depth, char **err_msg)
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)
List * lappend(List *list, void *datum)
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)
static char buf[DEFAULT_XLOG_SEG_SIZE]
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)
const char * gai_strerror(int errcode)
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
struct sockaddr_storage mask
struct sockaddr_storage addr
IPCompareMethod ip_cmp_method
struct sockaddr_storage addr