PostgreSQL Source Code  git master
hba.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <pwd.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "access/htup_details.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "common/ip.h"
#include "funcapi.h"
#include "libpq/ifaddr.h"
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "regex/regex.h"
#include "replication/walsender.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/varlena.h"
Include dependency graph for hba.c:

Go to the source code of this file.

Data Structures

struct  check_network_data
 
struct  HbaToken
 
struct  TokenizedLine
 

Macros

#define MAX_TOKEN   256
 
#define MAX_LINE   8192
 
#define token_is_keyword(t, k)   (!t->quoted && strcmp(t->string, k) == 0)
 
#define token_matches(t, k)   (strcmp(t->string, k) == 0)
 
#define INVALID_AUTH_OPTION(optname, validmethods)
 
#define REQUIRE_AUTH_OPTION(methodval, optname, validmethods)
 
#define MANDATORY_AUTH_ARG(argvar, argname, authname)
 
#define IDENT_FIELD_ABSENT(field)
 
#define IDENT_MULTI_VALUE(tokens)
 
#define MAX_HBA_OPTIONS   14
 
#define NUM_PG_HBA_FILE_RULES_ATTS   9
 

Typedefs

typedef struct check_network_data check_network_data
 
typedef struct HbaToken HbaToken
 
typedef struct TokenizedLine TokenizedLine
 

Functions

static MemoryContext tokenize_file (const char *filename, FILE *file, List **tok_lines, int elevel)
 
static Listtokenize_inc_file (List *tokens, const char *outer_filename, const char *inc_filename, int elevel, char **err_msg)
 
static bool parse_hba_auth_opt (char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg)
 
static bool verify_option_list_length (List *options, const char *optionname, List *masters, const char *mastername, int line_num)
 
static ArrayTypegethba_options (HbaLine *hba)
 
static void fill_hba_line (Tuplestorestate *tuple_store, TupleDesc tupdesc, int lineno, HbaLine *hba, const char *err_msg)
 
static void fill_hba_view (Tuplestorestate *tuple_store, TupleDesc tupdesc)
 
bool pg_isblank (const char c)
 
static bool next_token (char **lineptr, char *buf, int bufsz, bool *initial_quote, bool *terminating_comma, int elevel, char **err_msg)
 
static HbaTokenmake_hba_token (const char *token, bool quoted)
 
static HbaTokencopy_hba_token (HbaToken *in)
 
static Listnext_field_expand (const char *filename, char **lineptr, int elevel, char **err_msg)
 
static bool is_member (Oid userid, const char *role)
 
static bool check_role (const char *role, Oid roleid, List *tokens)
 
static bool check_db (const char *dbname, const char *role, Oid roleid, List *tokens)
 
static bool ipv4eq (struct sockaddr_in *a, struct sockaddr_in *b)
 
static bool hostname_match (const char *pattern, const char *actual_hostname)
 
static bool check_hostname (hbaPort *port, const char *hostname)
 
static bool check_ip (SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask)
 
static void check_network_callback (struct sockaddr *addr, struct sockaddr *netmask, void *cb_data)
 
static bool check_same_host_or_net (SockAddr *raddr, IPCompareMethod method)
 
static HbaLineparse_hba_line (TokenizedLine *tok_line, int elevel)
 
static void check_hba (hbaPort *port)
 
bool load_hba (void)
 
Datum pg_hba_file_rules (PG_FUNCTION_ARGS)
 
static IdentLineparse_ident_line (TokenizedLine *tok_line)
 
static void check_ident_usermap (IdentLine *identLine, const char *usermap_name, const char *pg_role, const char *ident_user, bool case_insensitive, bool *found_p, bool *error_p)
 
int check_usermap (const char *usermap_name, const char *pg_role, const char *auth_user, bool case_insensitive)
 
bool load_ident (void)
 
void hba_getauthmethod (hbaPort *port)
 

Variables

static Listparsed_hba_lines = NIL
 
static MemoryContext parsed_hba_context = NULL
 
static Listparsed_ident_lines = NIL
 
static MemoryContext parsed_ident_context = NULL
 
static const char *const UserAuthName []
 

Macro Definition Documentation

◆ IDENT_FIELD_ABSENT

#define IDENT_FIELD_ABSENT (   field)
Value:
do { \
if (!field) { \
ereport(LOG, \
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
errmsg("missing entry in file \"%s\" at end of line %d", \
IdentFileName, line_num))); \
return NULL; \
} \
} while (0)
int errcode(int sqlerrcode)
Definition: elog.c:608
#define LOG
Definition: elog.h:26
char * IdentFileName
Definition: guc.c:531
int errmsg(const char *fmt,...)
Definition: elog.c:822

Definition at line 908 of file hba.c.

Referenced by parse_ident_line().

◆ IDENT_MULTI_VALUE

#define IDENT_MULTI_VALUE (   tokens)
Value:
do { \
if (tokens->length > 1) { \
ereport(LOG, \
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
errmsg("multiple values in ident field"), \
errcontext("line %d of configuration file \"%s\"", \
line_num, IdentFileName))); \
return NULL; \
} \
} while (0)
int errcode(int sqlerrcode)
Definition: elog.c:608
#define LOG
Definition: elog.h:26
char * IdentFileName
Definition: guc.c:531
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define errcontext
Definition: elog.h:183

Definition at line 919 of file hba.c.

Referenced by parse_ident_line().

◆ INVALID_AUTH_OPTION

#define INVALID_AUTH_OPTION (   optname,
  validmethods 
)
Value:
do { \
ereport(elevel, \
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
/* translator: the second %s is a list of auth methods */ \
errmsg("authentication option \"%s\" is only valid for authentication methods %s", \
optname, _(validmethods)), \
errcontext("line %d of configuration file \"%s\"", \
line_num, HbaFileName))); \
*err_msg = psprintf("authentication option \"%s\" is only valid for authentication methods %s", \
optname, validmethods); \
return false; \
} while (0)
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
int errcode(int sqlerrcode)
Definition: elog.c:608
char * HbaFileName
Definition: guc.c:530
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define errcontext
Definition: elog.h:183
#define _(x)
Definition: elog.c:87

Definition at line 860 of file hba.c.

Referenced by parse_hba_auth_opt().

◆ MANDATORY_AUTH_ARG

#define MANDATORY_AUTH_ARG (   argvar,
  argname,
  authname 
)
Value:
do { \
if (argvar == NULL) { \
ereport(elevel, \
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
errmsg("authentication method \"%s\" requires argument \"%s\" to be set", \
authname, argname), \
errcontext("line %d of configuration file \"%s\"", \
line_num, HbaFileName))); \
*err_msg = psprintf("authentication method \"%s\" requires argument \"%s\" to be set", \
authname, argname); \
return NULL; \
} \
} while (0)
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
int errcode(int sqlerrcode)
Definition: elog.c:608
char * HbaFileName
Definition: guc.c:530
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define errcontext
Definition: elog.h:183

Definition at line 880 of file hba.c.

Referenced by parse_hba_line().

◆ MAX_HBA_OPTIONS

#define MAX_HBA_OPTIONS   14

Definition at line 2283 of file hba.c.

Referenced by gethba_options().

◆ MAX_LINE

#define MAX_LINE   8192

Definition at line 57 of file hba.c.

Referenced by tokenize_file().

◆ MAX_TOKEN

#define MAX_TOKEN   256

Definition at line 56 of file hba.c.

Referenced by next_field_expand().

◆ NUM_PG_HBA_FILE_RULES_ATTS

#define NUM_PG_HBA_FILE_RULES_ATTS   9

Definition at line 2399 of file hba.c.

Referenced by fill_hba_line().

◆ REQUIRE_AUTH_OPTION

#define REQUIRE_AUTH_OPTION (   methodval,
  optname,
  validmethods 
)
Value:
do { \
if (hbaline->auth_method != methodval) \
INVALID_AUTH_OPTION(optname, validmethods); \
} while (0)

Definition at line 874 of file hba.c.

Referenced by parse_hba_auth_opt().

◆ token_is_keyword

#define token_is_keyword (   t,
 
)    (!t->quoted && strcmp(t->string, k) == 0)

Definition at line 68 of file hba.c.

Referenced by check_db(), check_role(), and parse_hba_line().

◆ token_matches

#define token_matches (   t,
 
)    (strcmp(t->string, k) == 0)

Definition at line 69 of file hba.c.

Referenced by check_db(), and check_role().

Typedef Documentation

◆ check_network_data

◆ HbaToken

typedef struct HbaToken HbaToken

◆ TokenizedLine

typedef struct TokenizedLine TokenizedLine

Function Documentation

◆ check_db()

static bool check_db ( const char *  dbname,
const char *  role,
Oid  roleid,
List tokens 
)
static

Definition at line 610 of file hba.c.

References am_db_walsender, am_walsender, is_member(), lfirst, token_is_keyword, and token_matches.

Referenced by check_hba().

611 {
612  ListCell *cell;
613  HbaToken *tok;
614 
615  foreach(cell, tokens)
616  {
617  tok = lfirst(cell);
619  {
620  /*
621  * physical replication walsender connections can only match
622  * replication keyword
623  */
624  if (token_is_keyword(tok, "replication"))
625  return true;
626  }
627  else if (token_is_keyword(tok, "all"))
628  return true;
629  else if (token_is_keyword(tok, "sameuser"))
630  {
631  if (strcmp(dbname, role) == 0)
632  return true;
633  }
634  else if (token_is_keyword(tok, "samegroup") ||
635  token_is_keyword(tok, "samerole"))
636  {
637  if (is_member(roleid, dbname))
638  return true;
639  }
640  else if (token_is_keyword(tok, "replication"))
641  continue; /* never match this if not walsender */
642  else if (token_matches(tok, dbname))
643  return true;
644  }
645  return false;
646 }
#define token_matches(t, k)
Definition: hba.c:69
bool am_walsender
Definition: walsender.c:114
Definition: hba.c:75
bool am_db_walsender
Definition: walsender.c:117
#define lfirst(lc)
Definition: pg_list.h:190
char * dbname
Definition: streamutil.c:50
static bool is_member(Oid userid, const char *role)
Definition: hba.c:562
#define token_is_keyword(t, k)
Definition: hba.c:68

◆ check_hba()

static void check_hba ( hbaPort port)
static

Definition at line 2071 of file hba.c.

References SockAddr::addr, HbaLine::addr, HbaLine::auth_method, check_db(), check_hostname(), check_ip(), check_role(), check_same_host_or_net(), HbaLine::conntype, ctHostGSS, ctHostNoGSS, ctHostNoSSL, ctHostSSL, ctLocal, Port::database_name, HbaLine::databases, get_role_oid(), Port::gss, Port::hba, HbaLine::hostname, HbaLine::ip_cmp_method, ipCmpAll, ipCmpMask, ipCmpSameHost, ipCmpSameNet, IS_AF_UNIX, lfirst, HbaLine::mask, palloc0(), Port::raddr, HbaLine::roles, Port::ssl_in_use, uaImplicitReject, and Port::user_name.

Referenced by hba_getauthmethod().

2072 {
2073  Oid roleid;
2074  ListCell *line;
2075  HbaLine *hba;
2076 
2077  /* Get the target role's OID. Note we do not error out for bad role. */
2078  roleid = get_role_oid(port->user_name, true);
2079 
2080  foreach(line, parsed_hba_lines)
2081  {
2082  hba = (HbaLine *) lfirst(line);
2083 
2084  /* Check connection type */
2085  if (hba->conntype == ctLocal)
2086  {
2087  if (!IS_AF_UNIX(port->raddr.addr.ss_family))
2088  continue;
2089  }
2090  else
2091  {
2092  if (IS_AF_UNIX(port->raddr.addr.ss_family))
2093  continue;
2094 
2095  /* Check SSL state */
2096  if (port->ssl_in_use)
2097  {
2098  /* Connection is SSL, match both "host" and "hostssl" */
2099  if (hba->conntype == ctHostNoSSL)
2100  continue;
2101  }
2102  else
2103  {
2104  /* Connection is not SSL, match both "host" and "hostnossl" */
2105  if (hba->conntype == ctHostSSL)
2106  continue;
2107  }
2108 
2109  /* Check GSSAPI state */
2110 #ifdef ENABLE_GSS
2111  if (port->gss->enc && hba->conntype == ctHostNoGSS)
2112  continue;
2113  else if (!port->gss->enc && hba->conntype == ctHostGSS)
2114  continue;
2115 #else
2116  if (hba->conntype == ctHostGSS)
2117  continue;
2118 #endif
2119 
2120  /* Check IP address */
2121  switch (hba->ip_cmp_method)
2122  {
2123  case ipCmpMask:
2124  if (hba->hostname)
2125  {
2126  if (!check_hostname(port,
2127  hba->hostname))
2128  continue;
2129  }
2130  else
2131  {
2132  if (!check_ip(&port->raddr,
2133  (struct sockaddr *) &hba->addr,
2134  (struct sockaddr *) &hba->mask))
2135  continue;
2136  }
2137  break;
2138  case ipCmpAll:
2139  break;
2140  case ipCmpSameHost:
2141  case ipCmpSameNet:
2142  if (!check_same_host_or_net(&port->raddr,
2143  hba->ip_cmp_method))
2144  continue;
2145  break;
2146  default:
2147  /* shouldn't get here, but deem it no-match if so */
2148  continue;
2149  }
2150  } /* != ctLocal */
2151 
2152  /* Check database and role */
2153  if (!check_db(port->database_name, port->user_name, roleid,
2154  hba->databases))
2155  continue;
2156 
2157  if (!check_role(port->user_name, roleid, hba->roles))
2158  continue;
2159 
2160  /* Found a record that matched! */
2161  port->hba = hba;
2162  return;
2163  }
2164 
2165  /* If no matching entry was found, then implicitly reject. */
2166  hba = palloc0(sizeof(HbaLine));
2168  port->hba = hba;
2169 }
List * databases
Definition: hba.h:75
Definition: hba.h:70
struct sockaddr_storage mask
Definition: hba.h:78
Definition: hba.h:47
struct sockaddr_storage addr
Definition: pqcomm.h:64
bool ssl_in_use
Definition: libpq-be.h:190
unsigned int Oid
Definition: postgres_ext.h:31
static bool check_hostname(hbaPort *port, const char *hostname)
Definition: hba.c:693
static List * parsed_hba_lines
Definition: hba.c:101
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5183
SockAddr raddr
Definition: libpq-be.h:126
ConnType conntype
Definition: hba.h:74
Definition: hba.h:57
struct sockaddr_storage addr
Definition: hba.h:77
#define IS_AF_UNIX(fam)
Definition: ip.h:24
Definition: hba.h:59
static bool check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask)
Definition: hba.c:786
char * user_name
Definition: libpq-be.h:141
static bool check_role(const char *role, Oid roleid, List *tokens)
Definition: hba.c:586
Definition: hba.h:55
HbaLine * hba
Definition: libpq-be.h:155
Definition: hba.h:50
void * palloc0(Size size)
Definition: mcxt.c:980
char * hostname
Definition: hba.h:80
List * roles
Definition: hba.h:76
#define lfirst(lc)
Definition: pg_list.h:190
static bool check_db(const char *dbname, const char *role, Oid roleid, List *tokens)
Definition: hba.c:610
void * gss
Definition: libpq-be.h:184
static bool check_same_host_or_net(SockAddr *raddr, IPCompareMethod method)
Definition: hba.c:827
IPCompareMethod ip_cmp_method
Definition: hba.h:79
char * database_name
Definition: libpq-be.h:140
UserAuth auth_method
Definition: hba.h:81

◆ check_hostname()

static bool check_hostname ( hbaPort port,
const char *  hostname 
)
static

Definition at line 693 of file hba.c.

References SockAddr::addr, addrinfo::ai_addr, addrinfo::ai_next, DEBUG2, elog, freeaddrinfo, getaddrinfo, hostname_match(), ipv4eq(), NI_MAXHOST, NI_NAMEREQD, pg_getnameinfo_all(), pstrdup(), Port::raddr, Port::remote_hostname, Port::remote_hostname_errcode, Port::remote_hostname_resolv, and SockAddr::salen.

Referenced by check_hba().

694 {
695  struct addrinfo *gai_result,
696  *gai;
697  int ret;
698  bool found;
699 
700  /* Quick out if remote host name already known bad */
701  if (port->remote_hostname_resolv < 0)
702  return false;
703 
704  /* Lookup remote host name if not already done */
705  if (!port->remote_hostname)
706  {
707  char remote_hostname[NI_MAXHOST];
708 
709  ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
710  remote_hostname, sizeof(remote_hostname),
711  NULL, 0,
712  NI_NAMEREQD);
713  if (ret != 0)
714  {
715  /* remember failure; don't complain in the postmaster log yet */
716  port->remote_hostname_resolv = -2;
717  port->remote_hostname_errcode = ret;
718  return false;
719  }
720 
721  port->remote_hostname = pstrdup(remote_hostname);
722  }
723 
724  /* Now see if remote host name matches this pg_hba line */
726  return false;
727 
728  /* If we already verified the forward lookup, we're done */
729  if (port->remote_hostname_resolv == +1)
730  return true;
731 
732  /* Lookup IP from host name and check against original IP */
733  ret = getaddrinfo(port->remote_hostname, NULL, NULL, &gai_result);
734  if (ret != 0)
735  {
736  /* remember failure; don't complain in the postmaster log yet */
737  port->remote_hostname_resolv = -2;
738  port->remote_hostname_errcode = ret;
739  return false;
740  }
741 
742  found = false;
743  for (gai = gai_result; gai; gai = gai->ai_next)
744  {
745  if (gai->ai_addr->sa_family == port->raddr.addr.ss_family)
746  {
747  if (gai->ai_addr->sa_family == AF_INET)
748  {
749  if (ipv4eq((struct sockaddr_in *) gai->ai_addr,
750  (struct sockaddr_in *) &port->raddr.addr))
751  {
752  found = true;
753  break;
754  }
755  }
756 #ifdef HAVE_IPV6
757  else if (gai->ai_addr->sa_family == AF_INET6)
758  {
759  if (ipv6eq((struct sockaddr_in6 *) gai->ai_addr,
760  (struct sockaddr_in6 *) &port->raddr.addr))
761  {
762  found = true;
763  break;
764  }
765  }
766 #endif
767  }
768  }
769 
770  if (gai_result)
771  freeaddrinfo(gai_result);
772 
773  if (!found)
774  elog(DEBUG2, "pg_hba.conf host name \"%s\" rejected because address resolution did not return a match with IP address of client",
775  hostname);
776 
777  port->remote_hostname_resolv = found ? +1 : -1;
778 
779  return found;
780 }
#define getaddrinfo
Definition: getaddrinfo.h:136
#define NI_NAMEREQD
Definition: getaddrinfo.h:84
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define freeaddrinfo
Definition: getaddrinfo.h:141
struct sockaddr_storage addr
Definition: pqcomm.h:64
static bool ipv4eq(struct sockaddr_in *a, struct sockaddr_in *b)
Definition: hba.c:649
char * remote_hostname
Definition: libpq-be.h:128
SockAddr raddr
Definition: libpq-be.h:126
#define NI_MAXHOST
Definition: getaddrinfo.h:88
static bool hostname_match(const char *pattern, const char *actual_hostname)
Definition: hba.c:673
#define DEBUG2
Definition: elog.h:24
int remote_hostname_errcode
Definition: libpq-be.h:131
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:122
int remote_hostname_resolv
Definition: libpq-be.h:130
struct addrinfo * ai_next
Definition: getaddrinfo.h:107
#define elog(elevel,...)
Definition: elog.h:228
static char * hostname
Definition: pg_regress.c:90
struct sockaddr * ai_addr
Definition: getaddrinfo.h:105

◆ check_ident_usermap()

static void check_ident_usermap ( IdentLine identLine,
const char *  usermap_name,
const char *  pg_role,
const char *  ident_user,
bool  case_insensitive,
bool found_p,
bool error_p 
)
static

Definition at line 2788 of file hba.c.

References ereport, errcode(), errmsg(), IdentLine::ident_user, LOG, palloc(), palloc0(), pfree(), pg_mb2wchar_with_len(), pg_regerror(), pg_regexec(), IdentLine::pg_role, pg_strcasecmp(), pstrdup(), IdentLine::re, REG_NOMATCH, regmatch_t::rm_eo, regmatch_t::rm_so, and IdentLine::usermap.

Referenced by check_usermap().

2791 {
2792  *found_p = false;
2793  *error_p = false;
2794 
2795  if (strcmp(identLine->usermap, usermap_name) != 0)
2796  /* Line does not match the map name we're looking for, so just abort */
2797  return;
2798 
2799  /* Match? */
2800  if (identLine->ident_user[0] == '/')
2801  {
2802  /*
2803  * When system username starts with a slash, treat it as a regular
2804  * expression. In this case, we process the system username as a
2805  * regular expression that returns exactly one match. This is replaced
2806  * for \1 in the database username string, if present.
2807  */
2808  int r;
2809  regmatch_t matches[2];
2810  pg_wchar *wstr;
2811  int wlen;
2812  char *ofs;
2813  char *regexp_pgrole;
2814 
2815  wstr = palloc((strlen(ident_user) + 1) * sizeof(pg_wchar));
2816  wlen = pg_mb2wchar_with_len(ident_user, wstr, strlen(ident_user));
2817 
2818  r = pg_regexec(&identLine->re, wstr, wlen, 0, NULL, 2, matches, 0);
2819  if (r)
2820  {
2821  char errstr[100];
2822 
2823  if (r != REG_NOMATCH)
2824  {
2825  /* REG_NOMATCH is not an error, everything else is */
2826  pg_regerror(r, &identLine->re, errstr, sizeof(errstr));
2827  ereport(LOG,
2828  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
2829  errmsg("regular expression match for \"%s\" failed: %s",
2830  identLine->ident_user + 1, errstr)));
2831  *error_p = true;
2832  }
2833 
2834  pfree(wstr);
2835  return;
2836  }
2837  pfree(wstr);
2838 
2839  if ((ofs = strstr(identLine->pg_role, "\\1")) != NULL)
2840  {
2841  int offset;
2842 
2843  /* substitution of the first argument requested */
2844  if (matches[1].rm_so < 0)
2845  {
2846  ereport(LOG,
2847  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
2848  errmsg("regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"",
2849  identLine->ident_user + 1, identLine->pg_role)));
2850  *error_p = true;
2851  return;
2852  }
2853 
2854  /*
2855  * length: original length minus length of \1 plus length of match
2856  * plus null terminator
2857  */
2858  regexp_pgrole = palloc0(strlen(identLine->pg_role) - 2 + (matches[1].rm_eo - matches[1].rm_so) + 1);
2859  offset = ofs - identLine->pg_role;
2860  memcpy(regexp_pgrole, identLine->pg_role, offset);
2861  memcpy(regexp_pgrole + offset,
2862  ident_user + matches[1].rm_so,
2863  matches[1].rm_eo - matches[1].rm_so);
2864  strcat(regexp_pgrole, ofs + 2);
2865  }
2866  else
2867  {
2868  /* no substitution, so copy the match */
2869  regexp_pgrole = pstrdup(identLine->pg_role);
2870  }
2871 
2872  /*
2873  * now check if the username actually matched what the user is trying
2874  * to connect as
2875  */
2876  if (case_insensitive)
2877  {
2878  if (pg_strcasecmp(regexp_pgrole, pg_role) == 0)
2879  *found_p = true;
2880  }
2881  else
2882  {
2883  if (strcmp(regexp_pgrole, pg_role) == 0)
2884  *found_p = true;
2885  }
2886  pfree(regexp_pgrole);
2887 
2888  return;
2889  }
2890  else
2891  {
2892  /* Not regular expression, so make complete match */
2893  if (case_insensitive)
2894  {
2895  if (pg_strcasecmp(identLine->pg_role, pg_role) == 0 &&
2896  pg_strcasecmp(identLine->ident_user, ident_user) == 0)
2897  *found_p = true;
2898  }
2899  else
2900  {
2901  if (strcmp(identLine->pg_role, pg_role) == 0 &&
2902  strcmp(identLine->ident_user, ident_user) == 0)
2903  *found_p = true;
2904  }
2905  }
2906 }
regex_t re
Definition: hba.h:120
char * pstrdup(const char *in)
Definition: mcxt.c:1186
regoff_t rm_so
Definition: regex.h:85
int errcode(int sqlerrcode)
Definition: elog.c:608
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define LOG
Definition: elog.h:26
regoff_t rm_eo
Definition: regex.h:86
void pfree(void *pointer)
Definition: mcxt.c:1056
char * usermap
Definition: hba.h:117
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
#define ereport(elevel, rest)
Definition: elog.h:141
unsigned int pg_wchar
Definition: mbprint.c:31
void * palloc0(Size size)
Definition: mcxt.c:980
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:765
char * ident_user
Definition: hba.h:118
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)
Definition: regexec.c:172
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define REG_NOMATCH
Definition: regex.h:138
char * pg_role
Definition: hba.h:119

◆ check_ip()

static bool check_ip ( SockAddr raddr,
struct sockaddr *  addr,
struct sockaddr *  mask 
)
static

Definition at line 786 of file hba.c.

References SockAddr::addr, and pg_range_sockaddr().

Referenced by check_hba(), and check_network_callback().

787 {
788  if (raddr->addr.ss_family == addr->sa_family &&
789  pg_range_sockaddr(&raddr->addr,
790  (struct sockaddr_storage *) addr,
791  (struct sockaddr_storage *) mask))
792  return true;
793  return false;
794 }
struct sockaddr_storage addr
Definition: pqcomm.h:64
int pg_range_sockaddr(const struct sockaddr_storage *addr, const struct sockaddr_storage *netaddr, const struct sockaddr_storage *netmask)
Definition: ifaddr.c:53

◆ check_network_callback()

static void check_network_callback ( struct sockaddr *  addr,
struct sockaddr *  netmask,
void *  cb_data 
)
static

Definition at line 800 of file hba.c.

References check_ip(), ipCmpSameHost, check_network_data::method, pg_sockaddr_cidr_mask(), check_network_data::raddr, and check_network_data::result.

Referenced by check_same_host_or_net().

802 {
803  check_network_data *cn = (check_network_data *) cb_data;
804  struct sockaddr_storage mask;
805 
806  /* Already found a match? */
807  if (cn->result)
808  return;
809 
810  if (cn->method == ipCmpSameHost)
811  {
812  /* Make an all-ones netmask of appropriate length for family */
813  pg_sockaddr_cidr_mask(&mask, NULL, addr->sa_family);
814  cn->result = check_ip(cn->raddr, addr, (struct sockaddr *) &mask);
815  }
816  else
817  {
818  /* Use the netmask of the interface itself */
819  cn->result = check_ip(cn->raddr, addr, netmask);
820  }
821 }
SockAddr * raddr
Definition: hba.c:63
IPCompareMethod method
Definition: hba.c:62
int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
Definition: ifaddr.c:115
static bool check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask)
Definition: hba.c:786
bool result
Definition: hba.c:64

◆ check_role()

static bool check_role ( const char *  role,
Oid  roleid,
List tokens 
)
static

Definition at line 586 of file hba.c.

References is_member(), lfirst, HbaToken::quoted, HbaToken::string, token_is_keyword, and token_matches.

Referenced by check_hba().

587 {
588  ListCell *cell;
589  HbaToken *tok;
590 
591  foreach(cell, tokens)
592  {
593  tok = lfirst(cell);
594  if (!tok->quoted && tok->string[0] == '+')
595  {
596  if (is_member(roleid, tok->string + 1))
597  return true;
598  }
599  else if (token_matches(tok, role) ||
600  token_is_keyword(tok, "all"))
601  return true;
602  }
603  return false;
604 }
#define token_matches(t, k)
Definition: hba.c:69
Definition: hba.c:75
char * string
Definition: hba.c:77
bool quoted
Definition: hba.c:78
#define lfirst(lc)
Definition: pg_list.h:190
static bool is_member(Oid userid, const char *role)
Definition: hba.c:562
#define token_is_keyword(t, k)
Definition: hba.c:68

◆ check_same_host_or_net()

static bool check_same_host_or_net ( SockAddr raddr,
IPCompareMethod  method 
)
static

Definition at line 827 of file hba.c.

References check_network_callback(), elog, LOG, check_network_data::method, pg_foreach_ifaddr(), check_network_data::raddr, and check_network_data::result.

Referenced by check_hba().

828 {
830 
831  cn.method = method;
832  cn.raddr = raddr;
833  cn.result = false;
834 
835  errno = 0;
837  {
838  elog(LOG, "error enumerating network interfaces: %m");
839  return false;
840  }
841 
842  return cn.result;
843 }
SockAddr * raddr
Definition: hba.c:63
#define LOG
Definition: elog.h:26
IPCompareMethod method
Definition: hba.c:62
int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
Definition: ifaddr.c:559
static void check_network_callback(struct sockaddr *addr, struct sockaddr *netmask, void *cb_data)
Definition: hba.c:800
bool result
Definition: hba.c:64
#define elog(elevel,...)
Definition: elog.h:228

◆ check_usermap()

int check_usermap ( const char *  usermap_name,
const char *  pg_role,
const char *  auth_user,
bool  case_insensitive 
)

Definition at line 2923 of file hba.c.

References check_ident_usermap(), ereport, errmsg(), error(), lfirst, LOG, pg_strcasecmp(), STATUS_ERROR, and STATUS_OK.

Referenced by CheckSCRAMAuth(), and ident_inet().

2927 {
2928  bool found_entry = false,
2929  error = false;
2930 
2931  if (usermap_name == NULL || usermap_name[0] == '\0')
2932  {
2933  if (case_insensitive)
2934  {
2935  if (pg_strcasecmp(pg_role, auth_user) == 0)
2936  return STATUS_OK;
2937  }
2938  else
2939  {
2940  if (strcmp(pg_role, auth_user) == 0)
2941  return STATUS_OK;
2942  }
2943  ereport(LOG,
2944  (errmsg("provided user name (%s) and authenticated user name (%s) do not match",
2945  pg_role, auth_user)));
2946  return STATUS_ERROR;
2947  }
2948  else
2949  {
2950  ListCell *line_cell;
2951 
2952  foreach(line_cell, parsed_ident_lines)
2953  {
2954  check_ident_usermap(lfirst(line_cell), usermap_name,
2955  pg_role, auth_user, case_insensitive,
2956  &found_entry, &error);
2957  if (found_entry || error)
2958  break;
2959  }
2960  }
2961  if (!found_entry && !error)
2962  {
2963  ereport(LOG,
2964  (errmsg("no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"",
2965  usermap_name, pg_role, auth_user)));
2966  }
2967  return found_entry ? STATUS_OK : STATUS_ERROR;
2968 }
static void check_ident_usermap(IdentLine *identLine, const char *usermap_name, const char *pg_role, const char *ident_user, bool case_insensitive, bool *found_p, bool *error_p)
Definition: hba.c:2788
static void error(void)
Definition: sql-dyntest.c:147
#define STATUS_ERROR
Definition: c.h:1121
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define LOG
Definition: elog.h:26
#define ereport(elevel, rest)
Definition: elog.h:141
#define STATUS_OK
Definition: c.h:1120
static List * parsed_ident_lines
Definition: hba.c:112
#define lfirst(lc)
Definition: pg_list.h:190
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ copy_hba_token()

static HbaToken* copy_hba_token ( HbaToken in)
static

Definition at line 307 of file hba.c.

References make_hba_token(), HbaToken::quoted, and HbaToken::string.

Referenced by parse_hba_line(), and tokenize_inc_file().

308 {
309  HbaToken *out = make_hba_token(in->string, in->quoted);
310 
311  return out;
312 }
Definition: hba.c:75
char * string
Definition: hba.c:77
bool quoted
Definition: hba.c:78
static HbaToken * make_hba_token(const char *token, bool quoted)
Definition: hba.c:288

◆ fill_hba_line()

static void fill_hba_line ( Tuplestorestate tuple_store,
TupleDesc  tupdesc,
int  lineno,
HbaLine hba,
const char *  err_msg 
)
static

Definition at line 2414 of file hba.c.

References HbaLine::addr, Assert, HbaLine::auth_method, clean_ipv6_addr(), HbaLine::conntype, CStringGetTextDatum, ctHost, ctHostGSS, ctHostNoGSS, ctHostNoSSL, ctHostSSL, ctLocal, HbaLine::databases, gethba_options(), heap_form_tuple(), HbaLine::hostname, Int32GetDatum, HbaLine::ip_cmp_method, ipCmpAll, ipCmpMask, ipCmpSameHost, ipCmpSameNet, lappend(), lengthof, lfirst, HbaLine::mask, TupleDescData::natts, NI_MAXHOST, NI_NUMERICHOST, NIL, NUM_PG_HBA_FILE_RULES_ATTS, options, pg_getnameinfo_all(), PointerGetDatum, pstrdup(), HbaLine::roles, StaticAssertStmt, HbaToken::string, strlist_to_textarray(), tuplestore_puttuple(), USER_AUTH_LAST, UserAuthName, and values.

Referenced by fill_hba_view().

2416 {
2418  bool nulls[NUM_PG_HBA_FILE_RULES_ATTS];
2419  char buffer[NI_MAXHOST];
2420  HeapTuple tuple;
2421  int index;
2422  ListCell *lc;
2423  const char *typestr;
2424  const char *addrstr;
2425  const char *maskstr;
2426  ArrayType *options;
2427 
2429 
2430  memset(values, 0, sizeof(values));
2431  memset(nulls, 0, sizeof(nulls));
2432  index = 0;
2433 
2434  /* line_number */
2435  values[index++] = Int32GetDatum(lineno);
2436 
2437  if (hba != NULL)
2438  {
2439  /* type */
2440  /* Avoid a default: case so compiler will warn about missing cases */
2441  typestr = NULL;
2442  switch (hba->conntype)
2443  {
2444  case ctLocal:
2445  typestr = "local";
2446  break;
2447  case ctHost:
2448  typestr = "host";
2449  break;
2450  case ctHostSSL:
2451  typestr = "hostssl";
2452  break;
2453  case ctHostNoSSL:
2454  typestr = "hostnossl";
2455  break;
2456  case ctHostGSS:
2457  typestr = "hostgssenc";
2458  break;
2459  case ctHostNoGSS:
2460  typestr = "hostnogssenc";
2461  break;
2462  }
2463  if (typestr)
2464  values[index++] = CStringGetTextDatum(typestr);
2465  else
2466  nulls[index++] = true;
2467 
2468  /* database */
2469  if (hba->databases)
2470  {
2471  /*
2472  * Flatten HbaToken list to string list. It might seem that we
2473  * should re-quote any quoted tokens, but that has been rejected
2474  * on the grounds that it makes it harder to compare the array
2475  * elements to other system catalogs. That makes entries like
2476  * "all" or "samerole" formally ambiguous ... but users who name
2477  * databases/roles that way are inflicting their own pain.
2478  */
2479  List *names = NIL;
2480 
2481  foreach(lc, hba->databases)
2482  {
2483  HbaToken *tok = lfirst(lc);
2484 
2485  names = lappend(names, tok->string);
2486  }
2487  values[index++] = PointerGetDatum(strlist_to_textarray(names));
2488  }
2489  else
2490  nulls[index++] = true;
2491 
2492  /* user */
2493  if (hba->roles)
2494  {
2495  /* Flatten HbaToken list to string list; see comment above */
2496  List *roles = NIL;
2497 
2498  foreach(lc, hba->roles)
2499  {
2500  HbaToken *tok = lfirst(lc);
2501 
2502  roles = lappend(roles, tok->string);
2503  }
2504  values[index++] = PointerGetDatum(strlist_to_textarray(roles));
2505  }
2506  else
2507  nulls[index++] = true;
2508 
2509  /* address and netmask */
2510  /* Avoid a default: case so compiler will warn about missing cases */
2511  addrstr = maskstr = NULL;
2512  switch (hba->ip_cmp_method)
2513  {
2514  case ipCmpMask:
2515  if (hba->hostname)
2516  {
2517  addrstr = hba->hostname;
2518  }
2519  else
2520  {
2521  if (pg_getnameinfo_all(&hba->addr, sizeof(hba->addr),
2522  buffer, sizeof(buffer),
2523  NULL, 0,
2524  NI_NUMERICHOST) == 0)
2525  {
2526  clean_ipv6_addr(hba->addr.ss_family, buffer);
2527  addrstr = pstrdup(buffer);
2528  }
2529  if (pg_getnameinfo_all(&hba->mask, sizeof(hba->mask),
2530  buffer, sizeof(buffer),
2531  NULL, 0,
2532  NI_NUMERICHOST) == 0)
2533  {
2534  clean_ipv6_addr(hba->mask.ss_family, buffer);
2535  maskstr = pstrdup(buffer);
2536  }
2537  }
2538  break;
2539  case ipCmpAll:
2540  addrstr = "all";
2541  break;
2542  case ipCmpSameHost:
2543  addrstr = "samehost";
2544  break;
2545  case ipCmpSameNet:
2546  addrstr = "samenet";
2547  break;
2548  }
2549  if (addrstr)
2550  values[index++] = CStringGetTextDatum(addrstr);
2551  else
2552  nulls[index++] = true;
2553  if (maskstr)
2554  values[index++] = CStringGetTextDatum(maskstr);
2555  else
2556  nulls[index++] = true;
2557 
2558  /*
2559  * Make sure UserAuthName[] tracks additions to the UserAuth enum
2560  */
2562  "UserAuthName[] must match the UserAuth enum");
2563 
2564  /* auth_method */
2565  values[index++] = CStringGetTextDatum(UserAuthName[hba->auth_method]);
2566 
2567  /* options */
2568  options = gethba_options(hba);
2569  if (options)
2570  values[index++] = PointerGetDatum(options);
2571  else
2572  nulls[index++] = true;
2573  }
2574  else
2575  {
2576  /* no parsing result, so set relevant fields to nulls */
2577  memset(&nulls[1], true, (NUM_PG_HBA_FILE_RULES_ATTS - 2) * sizeof(bool));
2578  }
2579 
2580  /* error */
2581  if (err_msg)
2582  values[NUM_PG_HBA_FILE_RULES_ATTS - 1] = CStringGetTextDatum(err_msg);
2583  else
2584  nulls[NUM_PG_HBA_FILE_RULES_ATTS - 1] = true;
2585 
2586  tuple = heap_form_tuple(tupdesc, values, nulls);
2587  tuplestore_puttuple(tuple_store, tuple);
2588 }
List * databases
Definition: hba.h:75
#define NIL
Definition: pg_list.h:65
struct sockaddr_storage mask
Definition: hba.h:78
#define NI_NUMERICHOST
Definition: getaddrinfo.h:78
#define PointerGetDatum(X)
Definition: postgres.h:556
Definition: hba.h:47
char * pstrdup(const char *in)
Definition: mcxt.c:1186
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
static const char *const UserAuthName[]
Definition: hba.c:121
#define lengthof(array)
Definition: c.h:669
Definition: type.h:89
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:849
ConnType conntype
Definition: hba.h:74
Definition: hba.h:57
#define NI_MAXHOST
Definition: getaddrinfo.h:88
struct sockaddr_storage addr
Definition: hba.h:77
Definition: hba.h:59
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
Definition: tuplestore.c:730
Definition: hba.c:75
#define USER_AUTH_LAST
Definition: hba.h:42
Definition: hba.h:55
List * lappend(List *list, void *datum)
Definition: list.c:322
static char ** options
Definition: hba.h:50
uintptr_t Datum
Definition: postgres.h:367
char * hostname
Definition: hba.h:80
char * string
Definition: hba.c:77
List * roles
Definition: hba.h:76
#define Assert(condition)
Definition: c.h:739
#define lfirst(lc)
Definition: pg_list.h:190
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:122
#define NUM_PG_HBA_FILE_RULES_ATTS
Definition: hba.c:2399
void clean_ipv6_addr(int addr_family, char *addr)
Definition: network.c:2118
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define Int32GetDatum(X)
Definition: postgres.h:479
#define CStringGetTextDatum(s)
Definition: builtins.h:83
ArrayType * strlist_to_textarray(List *list)
IPCompareMethod ip_cmp_method
Definition: hba.h:79
Definition: pg_list.h:50
Definition: hba.h:56
UserAuth auth_method
Definition: hba.h:81
static ArrayType * gethba_options(HbaLine *hba)
Definition: hba.c:2290

◆ fill_hba_view()

static void fill_hba_view ( Tuplestorestate tuple_store,
TupleDesc  tupdesc 
)
static

Definition at line 2594 of file hba.c.

References AllocateFile(), ALLOCSET_SMALL_SIZES, AllocSetContextCreate, CurrentMemoryContext, DEBUG3, ereport, TokenizedLine::err_msg, errcode_for_file_access(), errmsg(), ERROR, fill_hba_line(), FreeFile(), HbaFileName, lfirst, TokenizedLine::line_num, MemoryContextDelete(), MemoryContextSwitchTo(), NIL, parse_hba_line(), and tokenize_file().

Referenced by pg_hba_file_rules().

2595 {
2596  FILE *file;
2597  List *hba_lines = NIL;
2598  ListCell *line;
2599  MemoryContext linecxt;
2600  MemoryContext hbacxt;
2601  MemoryContext oldcxt;
2602 
2603  /*
2604  * In the unlikely event that we can't open pg_hba.conf, we throw an
2605  * error, rather than trying to report it via some sort of view entry.
2606  * (Most other error conditions should result in a message in a view
2607  * entry.)
2608  */
2609  file = AllocateFile(HbaFileName, "r");
2610  if (file == NULL)
2611  ereport(ERROR,
2613  errmsg("could not open configuration file \"%s\": %m",
2614  HbaFileName)));
2615 
2616  linecxt = tokenize_file(HbaFileName, file, &hba_lines, DEBUG3);
2617  FreeFile(file);
2618 
2619  /* Now parse all the lines */
2621  "hba parser context",
2623  oldcxt = MemoryContextSwitchTo(hbacxt);
2624  foreach(line, hba_lines)
2625  {
2626  TokenizedLine *tok_line = (TokenizedLine *) lfirst(line);
2627  HbaLine *hbaline = NULL;
2628 
2629  /* don't parse lines that already have errors */
2630  if (tok_line->err_msg == NULL)
2631  hbaline = parse_hba_line(tok_line, DEBUG3);
2632 
2633  fill_hba_line(tuple_store, tupdesc, tok_line->line_num,
2634  hbaline, tok_line->err_msg);
2635  }
2636 
2637  /* Free tokenizer memory */
2638  MemoryContextDelete(linecxt);
2639  /* Free parse_hba_line memory */
2640  MemoryContextSwitchTo(oldcxt);
2641  MemoryContextDelete(hbacxt);
2642 }
Definition: hba.h:70
#define NIL
Definition: pg_list.h:65
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
#define DEBUG3
Definition: elog.h:23
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:202
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
char * HbaFileName
Definition: guc.c:530
#define ERROR
Definition: elog.h:43
int line_num
Definition: hba.c:92
char * err_msg
Definition: hba.c:94
int errcode_for_file_access(void)
Definition: elog.c:631
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2242
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
#define ereport(elevel, rest)
Definition: elog.h:141
static HbaLine * parse_hba_line(TokenizedLine *tok_line, int elevel)
Definition: hba.c:945
static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, int lineno, HbaLine *hba, const char *err_msg)
Definition: hba.c:2414
#define lfirst(lc)
Definition: pg_list.h:190
static MemoryContext tokenize_file(const char *filename, FILE *file, List **tok_lines, int elevel)
Definition: hba.c:470
int FreeFile(FILE *file)
Definition: fd.c:2441
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: pg_list.h:50

◆ gethba_options()

static ArrayType * gethba_options ( HbaLine hba)
static

Definition at line 2290 of file hba.c.

References Assert, HbaLine::auth_method, HbaLine::clientcert, clientCertCA, clientCertOff, construct_array(), CStringGetTextDatum, HbaLine::include_realm, HbaLine::krb_realm, HbaLine::ldapbasedn, HbaLine::ldapbinddn, HbaLine::ldapbindpasswd, HbaLine::ldapport, HbaLine::ldapprefix, HbaLine::ldapscope, HbaLine::ldapsearchattribute, HbaLine::ldapsearchfilter, HbaLine::ldapserver, HbaLine::ldapsuffix, HbaLine::ldaptls, MAX_HBA_OPTIONS, noptions, HbaLine::pamservice, psprintf(), HbaLine::radiusidentifiers_s, HbaLine::radiusports_s, HbaLine::radiussecrets_s, HbaLine::radiusservers_s, uaGSS, uaLDAP, uaRADIUS, uaSSPI, and HbaLine::usermap.

Referenced by fill_hba_line().

2291 {
2292  int noptions;
2294 
2295  noptions = 0;
2296 
2297  if (hba->auth_method == uaGSS || hba->auth_method == uaSSPI)
2298  {
2299  if (hba->include_realm)
2300  options[noptions++] =
2301  CStringGetTextDatum("include_realm=true");
2302 
2303  if (hba->krb_realm)
2304  options[noptions++] =
2305  CStringGetTextDatum(psprintf("krb_realm=%s", hba->krb_realm));
2306  }
2307 
2308  if (hba->usermap)
2309  options[noptions++] =
2310  CStringGetTextDatum(psprintf("map=%s", hba->usermap));
2311 
2312  if (hba->clientcert != clientCertOff)
2313  options[noptions++] =
2314  CStringGetTextDatum(psprintf("clientcert=%s", (hba->clientcert == clientCertCA) ? "verify-ca" : "verify-full"));
2315 
2316  if (hba->pamservice)
2317  options[noptions++] =
2318  CStringGetTextDatum(psprintf("pamservice=%s", hba->pamservice));
2319 
2320  if (hba->auth_method == uaLDAP)
2321  {
2322  if (hba->ldapserver)
2323  options[noptions++] =
2324  CStringGetTextDatum(psprintf("ldapserver=%s", hba->ldapserver));
2325 
2326  if (hba->ldapport)
2327  options[noptions++] =
2328  CStringGetTextDatum(psprintf("ldapport=%d", hba->ldapport));
2329 
2330  if (hba->ldaptls)
2331  options[noptions++] =
2332  CStringGetTextDatum("ldaptls=true");
2333 
2334  if (hba->ldapprefix)
2335  options[noptions++] =
2336  CStringGetTextDatum(psprintf("ldapprefix=%s", hba->ldapprefix));
2337 
2338  if (hba->ldapsuffix)
2339  options[noptions++] =
2340  CStringGetTextDatum(psprintf("ldapsuffix=%s", hba->ldapsuffix));
2341 
2342  if (hba->ldapbasedn)
2343  options[noptions++] =
2344  CStringGetTextDatum(psprintf("ldapbasedn=%s", hba->ldapbasedn));
2345 
2346  if (hba->ldapbinddn)
2347  options[noptions++] =
2348  CStringGetTextDatum(psprintf("ldapbinddn=%s", hba->ldapbinddn));
2349 
2350  if (hba->ldapbindpasswd)
2351  options[noptions++] =
2352  CStringGetTextDatum(psprintf("ldapbindpasswd=%s",
2353  hba->ldapbindpasswd));
2354 
2355  if (hba->ldapsearchattribute)
2356  options[noptions++] =
2357  CStringGetTextDatum(psprintf("ldapsearchattribute=%s",
2358  hba->ldapsearchattribute));
2359 
2360  if (hba->ldapsearchfilter)
2361  options[noptions++] =
2362  CStringGetTextDatum(psprintf("ldapsearchfilter=%s",
2363  hba->ldapsearchfilter));
2364 
2365  if (hba->ldapscope)
2366  options[noptions++] =
2367  CStringGetTextDatum(psprintf("ldapscope=%d", hba->ldapscope));
2368  }
2369 
2370  if (hba->auth_method == uaRADIUS)
2371  {
2372  if (hba->radiusservers_s)
2373  options[noptions++] =
2374  CStringGetTextDatum(psprintf("radiusservers=%s", hba->radiusservers_s));
2375 
2376  if (hba->radiussecrets_s)
2377  options[noptions++] =
2378  CStringGetTextDatum(psprintf("radiussecrets=%s", hba->radiussecrets_s));
2379 
2380  if (hba->radiusidentifiers_s)
2381  options[noptions++] =
2382  CStringGetTextDatum(psprintf("radiusidentifiers=%s", hba->radiusidentifiers_s));
2383 
2384  if (hba->radiusports_s)
2385  options[noptions++] =
2386  CStringGetTextDatum(psprintf("radiusports=%s", hba->radiusports_s));
2387  }
2388 
2389  /* If you add more options, consider increasing MAX_HBA_OPTIONS. */
2390  Assert(noptions <= MAX_HBA_OPTIONS);
2391 
2392  if (noptions > 0)
2393  return construct_array(options, noptions, TEXTOID, -1, false, 'i');
2394  else
2395  return NULL;
2396 }
int ldapscope
Definition: hba.h:95
char * radiusports_s
Definition: hba.h:110
char * ldapserver
Definition: hba.h:88
Definition: hba.h:38
int ldapport
Definition: hba.h:89
char * ldapbasedn
Definition: hba.h:94
char * pamservice
Definition: hba.h:84
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
Definition: hba.h:35
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3291
char * ldapsuffix
Definition: hba.h:97
Definition: hba.h:34
char * radiusservers_s
Definition: hba.h:104
char * usermap
Definition: hba.h:83
bool include_realm
Definition: hba.h:100
char * ldapbinddn
Definition: hba.h:90
char * krb_realm
Definition: hba.h:99
char * ldapbindpasswd
Definition: hba.h:91
char * ldapprefix
Definition: hba.h:96
uintptr_t Datum
Definition: postgres.h:367
char * radiusidentifiers_s
Definition: hba.h:108
char * radiussecrets_s
Definition: hba.h:106
#define Assert(condition)
Definition: c.h:739
char * ldapsearchfilter
Definition: hba.h:93
ClientCertMode clientcert
Definition: hba.h:98
bool ldaptls
Definition: hba.h:86
char * ldapsearchattribute
Definition: hba.h:92
#define CStringGetTextDatum(s)
Definition: builtins.h:83
static size_t noptions
Definition: hba.h:40
UserAuth auth_method
Definition: hba.h:81
#define MAX_HBA_OPTIONS
Definition: hba.c:2283

◆ hba_getauthmethod()

void hba_getauthmethod ( hbaPort port)

Definition at line 3089 of file hba.c.

References check_hba().

Referenced by ClientAuthentication().

3090 {
3091  check_hba(port);
3092 }
static void check_hba(hbaPort *port)
Definition: hba.c:2071

◆ hostname_match()

static bool hostname_match ( const char *  pattern,
const char *  actual_hostname 
)
static

Definition at line 673 of file hba.c.

References pg_strcasecmp().

Referenced by check_hostname().

674 {
675  if (pattern[0] == '.') /* suffix match */
676  {
677  size_t plen = strlen(pattern);
678  size_t hlen = strlen(actual_hostname);
679 
680  if (hlen < plen)
681  return false;
682 
683  return (pg_strcasecmp(pattern, actual_hostname + (hlen - plen)) == 0);
684  }
685  else
686  return (pg_strcasecmp(pattern, actual_hostname) == 0);
687 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36

◆ ipv4eq()

static bool ipv4eq ( struct sockaddr_in *  a,
struct sockaddr_in *  b 
)
static

Definition at line 649 of file hba.c.

References i.

Referenced by check_hostname().

650 {
651  return (a->sin_addr.s_addr == b->sin_addr.s_addr);
652 }

◆ is_member()

static bool is_member ( Oid  userid,
const char *  role 
)
static

Definition at line 562 of file hba.c.

References get_role_oid(), is_member_of_role_nosuper(), and OidIsValid.

Referenced by check_db(), and check_role().

563 {
564  Oid roleid;
565 
566  if (!OidIsValid(userid))
567  return false; /* if user not exist, say "no" */
568 
569  roleid = get_role_oid(role, true);
570 
571  if (!OidIsValid(roleid))
572  return false; /* if target role not exist, say "no" */
573 
574  /*
575  * See if user is directly or indirectly a member of role. For this
576  * purpose, a superuser is not considered to be automatically a member of
577  * the role, so group auth only applies to explicit membership.
578  */
579  return is_member_of_role_nosuper(userid, roleid);
580 }
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:645
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5183
bool is_member_of_role_nosuper(Oid member, Oid role)
Definition: acl.c:4962

◆ load_hba()

bool load_hba ( void  )

Definition at line 2183 of file hba.c.

References AllocateFile(), ALLOCSET_SMALL_SIZES, AllocSetContextCreate, Assert, ereport, TokenizedLine::err_msg, errcode(), errcode_for_file_access(), errmsg(), FreeFile(), HbaFileName, lappend(), lfirst, LOG, MemoryContextDelete(), MemoryContextSwitchTo(), newline(), NIL, parse_hba_line(), PostmasterContext, and tokenize_file().

Referenced by PerformAuthentication(), PostmasterMain(), and SIGHUP_handler().

2184 {
2185  FILE *file;
2186  List *hba_lines = NIL;
2187  ListCell *line;
2188  List *new_parsed_lines = NIL;
2189  bool ok = true;
2190  MemoryContext linecxt;
2191  MemoryContext oldcxt;
2192  MemoryContext hbacxt;
2193 
2194  file = AllocateFile(HbaFileName, "r");
2195  if (file == NULL)
2196  {
2197  ereport(LOG,
2199  errmsg("could not open configuration file \"%s\": %m",
2200  HbaFileName)));
2201  return false;
2202  }
2203 
2204  linecxt = tokenize_file(HbaFileName, file, &hba_lines, LOG);
2205  FreeFile(file);
2206 
2207  /* Now parse all the lines */
2210  "hba parser context",
2212  oldcxt = MemoryContextSwitchTo(hbacxt);
2213  foreach(line, hba_lines)
2214  {
2215  TokenizedLine *tok_line = (TokenizedLine *) lfirst(line);
2216  HbaLine *newline;
2217 
2218  /* don't parse lines that already have errors */
2219  if (tok_line->err_msg != NULL)
2220  {
2221  ok = false;
2222  continue;
2223  }
2224 
2225  if ((newline = parse_hba_line(tok_line, LOG)) == NULL)
2226  {
2227  /* Parse error; remember there's trouble */
2228  ok = false;
2229 
2230  /*
2231  * Keep parsing the rest of the file so we can report errors on
2232  * more than the first line. Error has already been logged, no
2233  * need for more chatter here.
2234  */
2235  continue;
2236  }
2237 
2238  new_parsed_lines = lappend(new_parsed_lines, newline);
2239  }
2240 
2241  /*
2242  * A valid HBA file must have at least one entry; else there's no way to
2243  * connect to the postmaster. But only complain about this if we didn't
2244  * already have parsing errors.
2245  */
2246  if (ok && new_parsed_lines == NIL)
2247  {
2248  ereport(LOG,
2249  (errcode(ERRCODE_CONFIG_FILE_ERROR),
2250  errmsg("configuration file \"%s\" contains no entries",
2251  HbaFileName)));
2252  ok = false;
2253  }
2254 
2255  /* Free tokenizer memory */
2256  MemoryContextDelete(linecxt);
2257  MemoryContextSwitchTo(oldcxt);
2258 
2259  if (!ok)
2260  {
2261  /* File contained one or more errors, so bail out */
2262  MemoryContextDelete(hbacxt);
2263  return false;
2264  }
2265 
2266  /* Loaded new file successfully, replace the one we use */
2267  if (parsed_hba_context != NULL)
2269  parsed_hba_context = hbacxt;
2270  parsed_hba_lines = new_parsed_lines;
2271 
2272  return true;
2273 }
Definition: hba.h:70
#define NIL
Definition: pg_list.h:65
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:202
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:608
#define LOG
Definition: elog.h:26
static chr newline(void)
Definition: regc_lex.c:1138
static List * parsed_hba_lines
Definition: hba.c:101
char * HbaFileName
Definition: guc.c:530
static MemoryContext parsed_hba_context
Definition: hba.c:102
char * err_msg
Definition: hba.c:94
int errcode_for_file_access(void)
Definition: elog.c:631
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2242
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:322
static HbaLine * parse_hba_line(TokenizedLine *tok_line, int elevel)
Definition: hba.c:945
#define Assert(condition)
Definition: c.h:739
#define lfirst(lc)
Definition: pg_list.h:190
static MemoryContext tokenize_file(const char *filename, FILE *file, List **tok_lines, int elevel)
Definition: hba.c:470
int FreeFile(FILE *file)
Definition: fd.c:2441
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: pg_list.h:50
MemoryContext PostmasterContext
Definition: mcxt.c:46

◆ load_ident()

bool load_ident ( void  )

Definition at line 2978 of file hba.c.

References AllocateFile(), ALLOCSET_SMALL_SIZES, AllocSetContextCreate, Assert, ereport, TokenizedLine::err_msg, errcode_for_file_access(), errmsg(), FreeFile(), IdentLine::ident_user, IdentFileName, lappend(), lfirst, LOG, MemoryContextDelete(), MemoryContextSwitchTo(), newline(), NIL, parse_ident_line(), pg_regfree(), PostmasterContext, IdentLine::re, and tokenize_file().

Referenced by PerformAuthentication(), PostmasterMain(), and SIGHUP_handler().

2979 {
2980  FILE *file;
2981  List *ident_lines = NIL;
2982  ListCell *line_cell,
2983  *parsed_line_cell;
2984  List *new_parsed_lines = NIL;
2985  bool ok = true;
2986  MemoryContext linecxt;
2987  MemoryContext oldcxt;
2988  MemoryContext ident_context;
2989  IdentLine *newline;
2990 
2991  file = AllocateFile(IdentFileName, "r");
2992  if (file == NULL)
2993  {
2994  /* not fatal ... we just won't do any special ident maps */
2995  ereport(LOG,
2997  errmsg("could not open usermap file \"%s\": %m",
2998  IdentFileName)));
2999  return false;
3000  }
3001 
3002  linecxt = tokenize_file(IdentFileName, file, &ident_lines, LOG);
3003  FreeFile(file);
3004 
3005  /* Now parse all the lines */
3007  ident_context = AllocSetContextCreate(PostmasterContext,
3008  "ident parser context",
3010  oldcxt = MemoryContextSwitchTo(ident_context);
3011  foreach(line_cell, ident_lines)
3012  {
3013  TokenizedLine *tok_line = (TokenizedLine *) lfirst(line_cell);
3014 
3015  /* don't parse lines that already have errors */
3016  if (tok_line->err_msg != NULL)
3017  {
3018  ok = false;
3019  continue;
3020  }
3021 
3022  if ((newline = parse_ident_line(tok_line)) == NULL)
3023  {
3024  /* Parse error; remember there's trouble */
3025  ok = false;
3026 
3027  /*
3028  * Keep parsing the rest of the file so we can report errors on
3029  * more than the first line. Error has already been logged, no
3030  * need for more chatter here.
3031  */
3032  continue;
3033  }
3034 
3035  new_parsed_lines = lappend(new_parsed_lines, newline);
3036  }
3037 
3038  /* Free tokenizer memory */
3039  MemoryContextDelete(linecxt);
3040  MemoryContextSwitchTo(oldcxt);
3041 
3042  if (!ok)
3043  {
3044  /*
3045  * File contained one or more errors, so bail out, first being careful
3046  * to clean up whatever we allocated. Most stuff will go away via
3047  * MemoryContextDelete, but we have to clean up regexes explicitly.
3048  */
3049  foreach(parsed_line_cell, new_parsed_lines)
3050  {
3051  newline = (IdentLine *) lfirst(parsed_line_cell);
3052  if (newline->ident_user[0] == '/')
3053  pg_regfree(&newline->re);
3054  }
3055  MemoryContextDelete(ident_context);
3056  return false;
3057  }
3058 
3059  /* Loaded new file successfully, replace the one we use */
3060  if (parsed_ident_lines != NIL)
3061  {
3062  foreach(parsed_line_cell, parsed_ident_lines)
3063  {
3064  newline = (IdentLine *) lfirst(parsed_line_cell);
3065  if (newline->ident_user[0] == '/')
3066  pg_regfree(&newline->re);
3067  }
3068  }
3069  if (parsed_ident_context != NULL)
3071 
3072  parsed_ident_context = ident_context;
3073  parsed_ident_lines = new_parsed_lines;
3074 
3075  return true;
3076 }
#define NIL
Definition: pg_list.h:65
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
regex_t re
Definition: hba.h:120
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:202
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define LOG
Definition: elog.h:26
static chr newline(void)
Definition: regc_lex.c:1138
char * err_msg
Definition: hba.c:94
int errcode_for_file_access(void)
Definition: elog.c:631
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2242
char * IdentFileName
Definition: guc.c:531
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:322
static List * parsed_ident_lines
Definition: hba.c:112
static MemoryContext parsed_ident_context
Definition: hba.c:113
#define Assert(condition)
Definition: c.h:739
#define lfirst(lc)
Definition: pg_list.h:190
static MemoryContext tokenize_file(const char *filename, FILE *file, List **tok_lines, int elevel)
Definition: hba.c:470
Definition: hba.h:113
int FreeFile(FILE *file)
Definition: fd.c:2441
char * ident_user
Definition: hba.h:118
int errmsg(const char *fmt,...)
Definition: elog.c:822
static IdentLine * parse_ident_line(TokenizedLine *tok_line)
Definition: hba.c:2711
void pg_regfree(regex_t *re)
Definition: regfree.c:49
Definition: pg_list.h:50
MemoryContext PostmasterContext
Definition: mcxt.c:46

◆ make_hba_token()

static HbaToken* make_hba_token ( const char *  token,
bool  quoted 
)
static

Definition at line 288 of file hba.c.

References palloc(), HbaToken::quoted, and HbaToken::string.

Referenced by copy_hba_token(), and next_field_expand().

289 {
290  HbaToken *hbatoken;
291  int toklen;
292 
293  toklen = strlen(token);
294  /* we copy string into same palloc block as the struct */
295  hbatoken = (HbaToken *) palloc(sizeof(HbaToken) + toklen + 1);
296  hbatoken->string = (char *) hbatoken + sizeof(HbaToken);
297  hbatoken->quoted = quoted;
298  memcpy(hbatoken->string, token, toklen + 1);
299 
300  return hbatoken;
301 }
Definition: hba.c:75
char * string
Definition: hba.c:77
bool quoted
Definition: hba.c:78
void * palloc(Size size)
Definition: mcxt.c:949

◆ next_field_expand()

static List* next_field_expand ( const char *  filename,
char **  lineptr,
int  elevel,
char **  err_msg 
)
static

Definition at line 330 of file hba.c.

References buf, lappend(), make_hba_token(), MAX_TOKEN, next_token(), NIL, and tokenize_inc_file().

Referenced by tokenize_file().

332 {
333  char buf[MAX_TOKEN];
334  bool trailing_comma;
335  bool initial_quote;
336  List *tokens = NIL;
337 
338  do
339  {
340  if (!next_token(lineptr, buf, sizeof(buf),
341  &initial_quote, &trailing_comma,
342  elevel, err_msg))
343  break;
344 
345  /* Is this referencing a file? */
346  if (!initial_quote && buf[0] == '@' && buf[1] != '\0')
347  tokens = tokenize_inc_file(tokens, filename, buf + 1,
348  elevel, err_msg);
349  else
350  tokens = lappend(tokens, make_hba_token(buf, initial_quote));
351  } while (trailing_comma && (*err_msg == NULL));
352 
353  return tokens;
354 }
#define NIL
Definition: pg_list.h:65
static bool next_token(char **lineptr, char *buf, int bufsz, bool *initial_quote, bool *terminating_comma, int elevel, char **err_msg)
Definition: hba.c:195
static char * buf
Definition: pg_test_fsync.c:67
List * lappend(List *list, void *datum)
Definition: list.c:322
static int elevel
Definition: vacuumlazy.c:143
#define MAX_TOKEN
Definition: hba.c:56
static char * filename
Definition: pg_dumpall.c:90
Definition: pg_list.h:50
static List * tokenize_inc_file(List *tokens, const char *outer_filename, const char *inc_filename, int elevel, char **err_msg)
Definition: hba.c:372
static HbaToken * make_hba_token(const char *token, bool quoted)
Definition: hba.c:288

◆ next_token()

static bool next_token ( char **  lineptr,
char *  buf,
int  bufsz,
bool initial_quote,
bool terminating_comma,
int  elevel,
char **  err_msg 
)
static

Definition at line 195 of file hba.c.

References Assert, buf, ereport, errcode(), errmsg(), and pg_isblank().

Referenced by base_yylex(), filtered_base_yylex(), and next_field_expand().

198 {
199  int c;
200  char *start_buf = buf;
201  char *end_buf = buf + (bufsz - 1);
202  bool in_quote = false;
203  bool was_quote = false;
204  bool saw_quote = false;
205 
206  Assert(end_buf > start_buf);
207 
208  *initial_quote = false;
209  *terminating_comma = false;
210 
211  /* Move over any whitespace and commas preceding the next token */
212  while ((c = (*(*lineptr)++)) != '\0' && (pg_isblank(c) || c == ','))
213  ;
214 
215  /*
216  * Build a token in buf of next characters up to EOL, unquoted comma, or
217  * unquoted whitespace.
218  */
219  while (c != '\0' &&
220  (!pg_isblank(c) || in_quote))
221  {
222  /* skip comments to EOL */
223  if (c == '#' && !in_quote)
224  {
225  while ((c = (*(*lineptr)++)) != '\0')
226  ;
227  break;
228  }
229 
230  if (buf >= end_buf)
231  {
232  *buf = '\0';
233  ereport(elevel,
234  (errcode(ERRCODE_CONFIG_FILE_ERROR),
235  errmsg("authentication file token too long, skipping: \"%s\"",
236  start_buf)));
237  *err_msg = "authentication file token too long";
238  /* Discard remainder of line */
239  while ((c = (*(*lineptr)++)) != '\0')
240  ;
241  /* Un-eat the '\0', in case we're called again */
242  (*lineptr)--;
243  return false;
244  }
245 
246  /* we do not pass back a terminating comma in the token */
247  if (c == ',' && !in_quote)
248  {
249  *terminating_comma = true;
250  break;
251  }
252 
253  if (c != '"' || was_quote)
254  *buf++ = c;
255 
256  /* Literal double-quote is two double-quotes */
257  if (in_quote && c == '"')
258  was_quote = !was_quote;
259  else
260  was_quote = false;
261 
262  if (c == '"')
263  {
264  in_quote = !in_quote;
265  saw_quote = true;
266  if (buf == start_buf)
267  *initial_quote = true;
268  }
269 
270  c = *(*lineptr)++;
271  }
272 
273  /*
274  * Un-eat the char right after the token (critical in case it is '\0',
275  * else next call will read past end of string).
276  */
277  (*lineptr)--;
278 
279  *buf = '\0';
280 
281  return (saw_quote || buf > start_buf);
282 }
bool pg_isblank(const char c)
Definition: hba.c:160
int errcode(int sqlerrcode)
Definition: elog.c:608
char * c
static char * buf
Definition: pg_test_fsync.c:67
#define ereport(elevel, rest)
Definition: elog.h:141
static int elevel
Definition: vacuumlazy.c:143
#define Assert(condition)
Definition: c.h:739
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ parse_hba_auth_opt()

static bool parse_hba_auth_opt ( char *  name,
char *  val,
HbaLine hbaline,
int  elevel,
char **  err_msg 
)
static

Definition at line 1678 of file hba.c.

References addrinfo::ai_family, addrinfo::ai_socktype, HbaLine::auth_method, HbaLine::clientcert, clientCertCA, clientCertFull, clientCertOff, HbaLine::compat_realm, HbaLine::conntype, ctHostSSL, ereport, errcode(), errcontext, errmsg(), gai_strerror, gettext_noop, HbaFileName, HbaLine::include_realm, INVALID_AUTH_OPTION, HbaLine::krb_realm, HbaLine::ldapbasedn, HbaLine::ldapbinddn, HbaLine::ldapbindpasswd, HbaLine::ldapport, HbaLine::ldapprefix, HbaLine::ldapscheme, HbaLine::ldapscope, HbaLine::ldapsearchattribute, HbaLine::ldapsearchfilter, HbaLine::ldapserver, HbaLine::ldapsuffix, HbaLine::ldaptls, lfirst, HbaLine::linenumber, list_free(), MemSet, HbaLine::pam_use_hostname, HbaLine::pamservice, pg_freeaddrinfo_all(), pg_getaddrinfo_all(), psprintf(), pstrdup(), HbaLine::radiusidentifiers, HbaLine::radiusidentifiers_s, HbaLine::radiusports, HbaLine::radiusports_s, HbaLine::radiussecrets, HbaLine::radiussecrets_s, HbaLine::radiusservers, HbaLine::radiusservers_s, REQUIRE_AUTH_OPTION, SplitGUCList(), uaCert, uaGSS, uaIdent, uaLDAP, uaPAM, uaRADIUS, uaSSPI, HbaLine::upn_username, and HbaLine::usermap.

Referenced by parse_hba_line().

1680 {
1681  int line_num = hbaline->linenumber;
1682 
1683 #ifdef USE_LDAP
1684  hbaline->ldapscope = LDAP_SCOPE_SUBTREE;
1685 #endif
1686 
1687  if (strcmp(name, "map") == 0)
1688  {
1689  if (hbaline->auth_method != uaIdent &&
1690  hbaline->auth_method != uaPeer &&
1691  hbaline->auth_method != uaGSS &&
1692  hbaline->auth_method != uaSSPI &&
1693  hbaline->auth_method != uaCert)
1694  INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, gssapi, sspi, and cert"));
1695  hbaline->usermap = pstrdup(val);
1696  }
1697  else if (strcmp(name, "clientcert") == 0)
1698  {
1699  if (hbaline->conntype != ctHostSSL)
1700  {
1701  ereport(elevel,
1702  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1703  errmsg("clientcert can only be configured for \"hostssl\" rows"),
1704  errcontext("line %d of configuration file \"%s\"",
1705  line_num, HbaFileName)));
1706  *err_msg = "clientcert can only be configured for \"hostssl\" rows";
1707  return false;
1708  }
1709  if (strcmp(val, "1") == 0
1710  || strcmp(val, "verify-ca") == 0)
1711  {
1712  hbaline->clientcert = clientCertCA;
1713  }
1714  else if (strcmp(val, "verify-full") == 0)
1715  {
1716  hbaline->clientcert = clientCertFull;
1717  }
1718  else if (strcmp(val, "0") == 0
1719  || strcmp(val, "no-verify") == 0)
1720  {
1721  if (hbaline->auth_method == uaCert)
1722  {
1723  ereport(elevel,
1724  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1725  errmsg("clientcert can not be set to \"no-verify\" when using \"cert\" authentication"),
1726  errcontext("line %d of configuration file \"%s\"",
1727  line_num, HbaFileName)));
1728  *err_msg = "clientcert can not be set to \"no-verify\" when using \"cert\" authentication";
1729  return false;
1730  }
1731  hbaline->clientcert = clientCertOff;
1732  }
1733  else
1734  {
1735  ereport(elevel,
1736  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1737  errmsg("invalid value for clientcert: \"%s\"", val),
1738  errcontext("line %d of configuration file \"%s\"",
1739  line_num, HbaFileName)));
1740  return false;
1741  }
1742  }
1743  else if (strcmp(name, "pamservice") == 0)
1744  {
1745  REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam");
1746  hbaline->pamservice = pstrdup(val);
1747  }
1748  else if (strcmp(name, "pam_use_hostname") == 0)
1749  {
1750  REQUIRE_AUTH_OPTION(uaPAM, "pam_use_hostname", "pam");
1751  if (strcmp(val, "1") == 0)
1752  hbaline->pam_use_hostname = true;
1753  else
1754  hbaline->pam_use_hostname = false;
1755 
1756  }
1757  else if (strcmp(name, "ldapurl") == 0)
1758  {
1759 #ifdef LDAP_API_FEATURE_X_OPENLDAP
1760  LDAPURLDesc *urldata;
1761  int rc;
1762 #endif
1763 
1764  REQUIRE_AUTH_OPTION(uaLDAP, "ldapurl", "ldap");
1765 #ifdef LDAP_API_FEATURE_X_OPENLDAP
1766  rc = ldap_url_parse(val, &urldata);
1767  if (rc != LDAP_SUCCESS)
1768  {
1769  ereport(elevel,
1770  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1771  errmsg("could not parse LDAP URL \"%s\": %s", val, ldap_err2string(rc))));
1772  *err_msg = psprintf("could not parse LDAP URL \"%s\": %s",
1773  val, ldap_err2string(rc));
1774  return false;
1775  }
1776 
1777  if (strcmp(urldata->lud_scheme, "ldap") != 0 &&
1778  strcmp(urldata->lud_scheme, "ldaps") != 0)
1779  {
1780  ereport(elevel,
1781  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1782  errmsg("unsupported LDAP URL scheme: %s", urldata->lud_scheme)));
1783  *err_msg = psprintf("unsupported LDAP URL scheme: %s",
1784  urldata->lud_scheme);
1785  ldap_free_urldesc(urldata);
1786  return false;
1787  }
1788 
1789  if (urldata->lud_scheme)
1790  hbaline->ldapscheme = pstrdup(urldata->lud_scheme);
1791  if (urldata->lud_host)
1792  hbaline->ldapserver = pstrdup(urldata->lud_host);
1793  hbaline->ldapport = urldata->lud_port;
1794  if (urldata->lud_dn)
1795  hbaline->ldapbasedn = pstrdup(urldata->lud_dn);
1796 
1797  if (urldata->lud_attrs)
1798  hbaline->ldapsearchattribute = pstrdup(urldata->lud_attrs[0]); /* only use first one */
1799  hbaline->ldapscope = urldata->lud_scope;
1800  if (urldata->lud_filter)
1801  hbaline->ldapsearchfilter = pstrdup(urldata->lud_filter);
1802  ldap_free_urldesc(urldata);
1803 #else /* not OpenLDAP */
1804  ereport(elevel,
1805  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1806  errmsg("LDAP URLs not supported on this platform")));
1807  *err_msg = "LDAP URLs not supported on this platform";
1808 #endif /* not OpenLDAP */
1809  }
1810  else if (strcmp(name, "ldaptls") == 0)
1811  {
1812  REQUIRE_AUTH_OPTION(uaLDAP, "ldaptls", "ldap");
1813  if (strcmp(val, "1") == 0)
1814  hbaline->ldaptls = true;
1815  else
1816  hbaline->ldaptls = false;
1817  }
1818  else if (strcmp(name, "ldapscheme") == 0)
1819  {
1820  REQUIRE_AUTH_OPTION(uaLDAP, "ldapscheme", "ldap");
1821  if (strcmp(val, "ldap") != 0 && strcmp(val, "ldaps") != 0)
1822  ereport(elevel,
1823  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1824  errmsg("invalid ldapscheme value: \"%s\"", val),
1825  errcontext("line %d of configuration file \"%s\"",
1826  line_num, HbaFileName)));
1827  hbaline->ldapscheme = pstrdup(val);
1828  }
1829  else if (strcmp(name, "ldapserver") == 0)
1830  {
1831  REQUIRE_AUTH_OPTION(uaLDAP, "ldapserver", "ldap");
1832  hbaline->ldapserver = pstrdup(val);
1833  }
1834  else if (strcmp(name, "ldapport") == 0)
1835  {
1836  REQUIRE_AUTH_OPTION(uaLDAP, "ldapport", "ldap");
1837  hbaline->ldapport = atoi(val);
1838  if (hbaline->ldapport == 0)
1839  {
1840  ereport(elevel,
1841  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1842  errmsg("invalid LDAP port number: \"%s\"", val),
1843  errcontext("line %d of configuration file \"%s\"",
1844  line_num, HbaFileName)));
1845  *err_msg = psprintf("invalid LDAP port number: \"%s\"", val);
1846  return false;
1847  }
1848  }
1849  else if (strcmp(name, "ldapbinddn") == 0)
1850  {
1851  REQUIRE_AUTH_OPTION(uaLDAP, "ldapbinddn", "ldap");
1852  hbaline->ldapbinddn = pstrdup(val);
1853  }
1854  else if (strcmp(name, "ldapbindpasswd") == 0)
1855  {
1856  REQUIRE_AUTH_OPTION(uaLDAP, "ldapbindpasswd", "ldap");
1857  hbaline->ldapbindpasswd = pstrdup(val);
1858  }
1859  else if (strcmp(name, "ldapsearchattribute") == 0)
1860  {
1861  REQUIRE_AUTH_OPTION(uaLDAP, "ldapsearchattribute", "ldap");
1862  hbaline->ldapsearchattribute = pstrdup(val);
1863  }
1864  else if (strcmp(name, "ldapsearchfilter") == 0)
1865  {
1866  REQUIRE_AUTH_OPTION(uaLDAP, "ldapsearchfilter", "ldap");
1867  hbaline->ldapsearchfilter = pstrdup(val);
1868  }
1869  else if (strcmp(name, "ldapbasedn") == 0)
1870  {
1871  REQUIRE_AUTH_OPTION(uaLDAP, "ldapbasedn", "ldap");
1872  hbaline->ldapbasedn = pstrdup(val);
1873  }
1874  else if (strcmp(name, "ldapprefix") == 0)
1875  {
1876  REQUIRE_AUTH_OPTION(uaLDAP, "ldapprefix", "ldap");
1877  hbaline->ldapprefix = pstrdup(val);
1878  }
1879  else if (strcmp(name, "ldapsuffix") == 0)
1880  {
1881  REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap");
1882  hbaline->ldapsuffix = pstrdup(val);
1883  }
1884  else if (strcmp(name, "krb_realm") == 0)
1885  {
1886  if (hbaline->auth_method != uaGSS &&
1887  hbaline->auth_method != uaSSPI)
1888  INVALID_AUTH_OPTION("krb_realm", gettext_noop("gssapi and sspi"));
1889  hbaline->krb_realm = pstrdup(val);
1890  }
1891  else if (strcmp(name, "include_realm") == 0)
1892  {
1893  if (hbaline->auth_method != uaGSS &&
1894  hbaline->auth_method != uaSSPI)
1895  INVALID_AUTH_OPTION("include_realm", gettext_noop("gssapi and sspi"));
1896  if (strcmp(val, "1") == 0)
1897  hbaline->include_realm = true;
1898  else
1899  hbaline->include_realm = false;
1900  }
1901  else if (strcmp(name, "compat_realm") == 0)
1902  {
1903  if (hbaline->auth_method != uaSSPI)
1904  INVALID_AUTH_OPTION("compat_realm", gettext_noop("sspi"));
1905  if (strcmp(val, "1") == 0)
1906  hbaline->compat_realm = true;
1907  else
1908  hbaline->compat_realm = false;
1909  }
1910  else if (strcmp(name, "upn_username") == 0)
1911  {
1912  if (hbaline->auth_method != uaSSPI)
1913  INVALID_AUTH_OPTION("upn_username", gettext_noop("sspi"));
1914  if (strcmp(val, "1") == 0)
1915  hbaline->upn_username = true;
1916  else
1917  hbaline->upn_username = false;
1918  }
1919  else if (strcmp(name, "radiusservers") == 0)
1920  {
1921  struct addrinfo *gai_result;
1922  struct addrinfo hints;
1923  int ret;
1924  List *parsed_servers;
1925  ListCell *l;
1926  char *dupval = pstrdup(val);
1927 
1928  REQUIRE_AUTH_OPTION(uaRADIUS, "radiusservers", "radius");
1929 
1930  if (!SplitGUCList(dupval, ',', &parsed_servers))
1931  {
1932  /* syntax error in list */
1933  ereport(elevel,
1934  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1935  errmsg("could not parse RADIUS server list \"%s\"",
1936  val),
1937  errcontext("line %d of configuration file \"%s\"",
1938  line_num, HbaFileName)));
1939  return false;
1940  }
1941 
1942  /* For each entry in the list, translate it */
1943  foreach(l, parsed_servers)
1944  {
1945  MemSet(&hints, 0, sizeof(hints));
1946  hints.ai_socktype = SOCK_DGRAM;
1947  hints.ai_family = AF_UNSPEC;
1948 
1949  ret = pg_getaddrinfo_all((char *) lfirst(l), NULL, &hints, &gai_result);
1950  if (ret || !gai_result)
1951  {
1952  ereport(elevel,
1953  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1954  errmsg("could not translate RADIUS server name \"%s\" to address: %s",
1955  (char *) lfirst(l), gai_strerror(ret)),
1956  errcontext("line %d of configuration file \"%s\"",
1957  line_num, HbaFileName)));
1958  if (gai_result)
1959  pg_freeaddrinfo_all(hints.ai_family, gai_result);
1960 
1961  list_free(parsed_servers);
1962  return false;
1963  }
1964  pg_freeaddrinfo_all(hints.ai_family, gai_result);
1965  }
1966 
1967  /* All entries are OK, so store them */
1968  hbaline->radiusservers = parsed_servers;
1969  hbaline->radiusservers_s = pstrdup(val);
1970  }
1971  else if (strcmp(name, "radiusports") == 0)
1972  {
1973  List *parsed_ports;
1974  ListCell *l;
1975  char *dupval = pstrdup(val);
1976 
1977  REQUIRE_AUTH_OPTION(uaRADIUS, "radiusports", "radius");
1978 
1979  if (!SplitGUCList(dupval, ',', &parsed_ports))
1980  {
1981  ereport(elevel,
1982  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1983  errmsg("could not parse RADIUS port list \"%s\"",
1984  val),
1985  errcontext("line %d of configuration file \"%s\"",
1986  line_num, HbaFileName)));
1987  *err_msg = psprintf("invalid RADIUS port number: \"%s\"", val);
1988  return false;
1989  }
1990 
1991  foreach(l, parsed_ports)
1992  {
1993  if (atoi(lfirst(l)) == 0)
1994  {
1995  ereport(elevel,
1996  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1997  errmsg("invalid RADIUS port number: \"%s\"", val),
1998  errcontext("line %d of configuration file \"%s\"",
1999  line_num, HbaFileName)));
2000 
2001  return false;
2002  }
2003  }
2004  hbaline->radiusports = parsed_ports;
2005  hbaline->radiusports_s = pstrdup(val);
2006  }
2007  else if (strcmp(name, "radiussecrets") == 0)
2008  {
2009  List *parsed_secrets;
2010  char *dupval = pstrdup(val);
2011 
2012  REQUIRE_AUTH_OPTION(uaRADIUS, "radiussecrets", "radius");
2013 
2014  if (!SplitGUCList(dupval, ',', &parsed_secrets))
2015  {
2016  /* syntax error in list */
2017  ereport(elevel,
2018  (errcode(ERRCODE_CONFIG_FILE_ERROR),
2019  errmsg("could not parse RADIUS secret list \"%s\"",
2020  val),
2021  errcontext("line %d of configuration file \"%s\"",
2022  line_num, HbaFileName)));
2023  return false;
2024  }
2025 
2026  hbaline->radiussecrets = parsed_secrets;
2027  hbaline->radiussecrets_s = pstrdup(val);
2028  }
2029  else if (strcmp(name, "radiusidentifiers") == 0)
2030  {
2031  List *parsed_identifiers;
2032  char *dupval = pstrdup(val);
2033 
2034  REQUIRE_AUTH_OPTION(uaRADIUS, "radiusidentifiers", "radius");
2035 
2036  if (!SplitGUCList(dupval, ',', &parsed_identifiers))
2037  {
2038  /* syntax error in list */
2039  ereport(elevel,
2040  (errcode(ERRCODE_CONFIG_FILE_ERROR),
2041  errmsg("could not parse RADIUS identifiers list \"%s\"",
2042  val),
2043  errcontext("line %d of configuration file \"%s\"",
2044  line_num, HbaFileName)));
2045  return false;
2046  }
2047 
2048  hbaline->radiusidentifiers = parsed_identifiers;
2049  hbaline->radiusidentifiers_s = pstrdup(val);
2050  }
2051  else
2052  {
2053  ereport(elevel,
2054  (errcode(ERRCODE_CONFIG_FILE_ERROR),
2055  errmsg("unrecognized authentication option name: \"%s\"",
2056  name),
2057  errcontext("line %d of configuration file \"%s\"",
2058  line_num, HbaFileName)));
2059  *err_msg = psprintf("unrecognized authentication option name: \"%s\"",
2060  name);
2061  return false;
2062  }
2063  return true;
2064 }
int ldapscope
Definition: hba.h:95
char * radiusports_s
Definition: hba.h:110
Definition: hba.h:30
char * ldapserver
Definition: hba.h:88
#define REQUIRE_AUTH_OPTION(methodval, optname, validmethods)
Definition: hba.c:874
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
Definition: ip.c:88
Definition: hba.h:38
int ldapport
Definition: hba.h:89
char * ldapbasedn
Definition: hba.h:94
char * ldapscheme
Definition: hba.h:87
char * pamservice
Definition: hba.h:84
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
Definition: hba.h:35
#define gettext_noop(x)
Definition: c.h:1148
int errcode(int sqlerrcode)
Definition: elog.c:608
#define MemSet(start, val, len)
Definition: c.h:962
List * radiussecrets
Definition: hba.h:105
#define gai_strerror
Definition: getaddrinfo.h:146
char * ldapsuffix
Definition: hba.h:97
char * HbaFileName
Definition: guc.c:530
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
Definition: ip.c:57
#define INVALID_AUTH_OPTION(optname, validmethods)
Definition: hba.c:860
Definition: hba.h:34
ConnType conntype
Definition: hba.h:74
char * radiusservers_s
Definition: hba.h:104
Definition: hba.h:57
bool pam_use_hostname
Definition: hba.h:85
Definition: hba.h:39
char * usermap
Definition: hba.h:83
List * radiusports
Definition: hba.h:109
List * radiusservers
Definition: hba.h:103
bool include_realm
Definition: hba.h:100
char * ldapbinddn
Definition: hba.h:90
char * krb_realm
Definition: hba.h:99
int linenumber
Definition: hba.h:72
char * ldapbindpasswd
Definition: hba.h:91
#define ereport(elevel, rest)
Definition: elog.h:141
char * ldapprefix
Definition: hba.h:96
static int elevel
Definition: vacuumlazy.c:143
char * radiusidentifiers_s
Definition: hba.h:108
List * radiusidentifiers
Definition: hba.h:107
char * radiussecrets_s
Definition: hba.h:106
#define lfirst(lc)
Definition: pg_list.h:190
char * ldapsearchfilter
Definition: hba.h:93
ClientCertMode clientcert
Definition: hba.h:98
bool ldaptls
Definition: hba.h:86
char * ldapsearchattribute
Definition: hba.h:92
const char * name
Definition: encode.c:521
bool upn_username
Definition: hba.h:102
int errmsg(const char *fmt,...)
Definition: elog.c:822
void list_free(List *list)
Definition: list.c:1377
#define errcontext
Definition: elog.h:183
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3900
Definition: pg_list.h:50
Definition: hba.h:36
bool compat_realm
Definition: hba.h:101
long val
Definition: informix.c:664
Definition: hba.h:40
UserAuth auth_method
Definition: hba.h:81

◆ parse_hba_line()

static HbaLine* parse_hba_line ( TokenizedLine tok_line,
int  elevel 
)
static

Definition at line 945 of file hba.c.

References HbaLine::addr, addrinfo::ai_addr, addrinfo::ai_addrlen, addrinfo::ai_canonname, addrinfo::ai_family, addrinfo::ai_flags, addrinfo::ai_next, AI_NUMERICHOST, addrinfo::ai_protocol, addrinfo::ai_socktype, Assert, HbaLine::auth_method, HbaLine::clientcert, clientCertCA, HbaLine::compat_realm, HbaLine::conntype, copy_hba_token(), ctHost, ctHostGSS, ctHostNoGSS, ctHostNoSSL, ctHostSSL, ctLocal, HbaLine::databases, Db_user_namespace, EAI_NONAME, EnableSSL, ereport, TokenizedLine::err_msg, errcode(), errcontext, errhint(), errmsg(), TokenizedLine::fields, gai_strerror, HbaFileName, HbaLine::hostname, HbaLine::include_realm, HbaLine::ip_cmp_method, ipCmpAll, ipCmpMask, ipCmpSameHost, ipCmpSameNet, lappend(), HbaLine::ldapbasedn, HbaLine::ldapbinddn, HbaLine::ldapbindpasswd, HbaLine::ldapprefix, HbaLine::ldapsearchattribute, HbaLine::ldapsearchfilter, HbaLine::ldapserver, HbaLine::ldapsuffix, List::length, lfirst, TokenizedLine::line_num, HbaLine::linenumber, linitial, list_head(), list_length(), lnext(), LOG, MANDATORY_AUTH_ARG, HbaLine::mask, NIL, palloc0(), parse_hba_auth_opt(), pfree(), pg_freeaddrinfo_all(), pg_getaddrinfo_all(), pg_sockaddr_cidr_mask(), psprintf(), pstrdup(), HbaLine::radiusidentifiers, HbaLine::radiusports, HbaLine::radiussecrets, HbaLine::radiusservers, TokenizedLine::raw_line, HbaLine::rawline, HbaLine::roles, generate_unaccent_rules::str, HbaToken::string, token_is_keyword, uaBSD, uaCert, uaGSS, uaIdent, uaLDAP, uaMD5, uaPAM, uaPassword, uaRADIUS, uaReject, uaSCRAM, uaSSPI, uaTrust, HbaLine::upn_username, val, and verify_option_list_length().

Referenced by fill_hba_view(), and load_hba().

946 {
947  int line_num = tok_line->line_num;
948  char **err_msg = &tok_line->err_msg;
949  char *str;
950  struct addrinfo *gai_result;
951  struct addrinfo hints;
952  int ret;
953  char *cidr_slash;
954  char *unsupauth;
955  ListCell *field;
956  List *tokens;
957  ListCell *tokencell;
958  HbaToken *token;
959  HbaLine *parsedline;
960 
961  parsedline = palloc0(sizeof(HbaLine));
962  parsedline->linenumber = line_num;
963  parsedline->rawline = pstrdup(tok_line->raw_line);
964 
965  /* Check the record type. */
966  Assert(tok_line->fields != NIL);
967  field = list_head(tok_line->fields);
968  tokens = lfirst(field);
969  if (tokens->length > 1)
970  {
971  ereport(elevel,
972  (errcode(ERRCODE_CONFIG_FILE_ERROR),
973  errmsg("multiple values specified for connection type"),
974  errhint("Specify exactly one connection type per line."),
975  errcontext("line %d of configuration file \"%s\"",
976  line_num, HbaFileName)));
977  *err_msg = "multiple values specified for connection type";
978  return NULL;
979  }
980  token = linitial(tokens);
981  if (strcmp(token->string, "local") == 0)
982  {
983 #ifdef HAVE_UNIX_SOCKETS
984  parsedline->conntype = ctLocal;
985 #else
986  ereport(elevel,
987  (errcode(ERRCODE_CONFIG_FILE_ERROR),
988  errmsg("local connections are not supported by this build"),
989  errcontext("line %d of configuration file \"%s\"",
990  line_num, HbaFileName)));
991  *err_msg = "local connections are not supported by this build";
992  return NULL;
993 #endif
994  }
995  else if (strcmp(token->string, "host") == 0 ||
996  strcmp(token->string, "hostssl") == 0 ||
997  strcmp(token->string, "hostnossl") == 0 ||
998  strcmp(token->string, "hostgssenc") == 0 ||
999  strcmp(token->string, "hostnogssenc") == 0)
1000  {
1001 
1002  if (token->string[4] == 's') /* "hostssl" */
1003  {
1004  parsedline->conntype = ctHostSSL;
1005  /* Log a warning if SSL support is not active */
1006 #ifdef USE_SSL
1007  if (!EnableSSL)
1008  {
1009  ereport(elevel,
1010  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1011  errmsg("hostssl record cannot match because SSL is disabled"),
1012  errhint("Set ssl = on in postgresql.conf."),
1013  errcontext("line %d of configuration file \"%s\"",
1014  line_num, HbaFileName)));
1015  *err_msg = "hostssl record cannot match because SSL is disabled";
1016  }
1017 #else
1018  ereport(elevel,
1019  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1020  errmsg("hostssl record cannot match because SSL is not supported by this build"),
1021  errhint("Compile with --with-openssl to use SSL connections."),
1022  errcontext("line %d of configuration file \"%s\"",
1023  line_num, HbaFileName)));
1024  *err_msg = "hostssl record cannot match because SSL is not supported by this build";
1025 #endif
1026  }
1027  else if (token->string[4] == 'g') /* "hostgssenc" */
1028  {
1029  parsedline->conntype = ctHostGSS;
1030 #ifndef ENABLE_GSS
1031  ereport(elevel,
1032  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1033  errmsg("hostgssenc record cannot match because GSSAPI is not supported by this build"),
1034  errhint("Compile with --with-gssapi to use GSSAPI connections."),
1035  errcontext("line %d of configuration file \"%s\"",
1036  line_num, HbaFileName)));
1037  *err_msg = "hostgssenc record cannot match because GSSAPI is not supported by this build";
1038 #endif
1039  }
1040  else if (token->string[4] == 'n' && token->string[6] == 's')
1041  parsedline->conntype = ctHostNoSSL;
1042  else if (token->string[4] == 'n' && token->string[6] == 'g')
1043  parsedline->conntype = ctHostNoGSS;
1044  else
1045  {
1046  /* "host" */
1047  parsedline->conntype = ctHost;
1048  }
1049  } /* record type */
1050  else
1051  {
1052  ereport(elevel,
1053  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1054  errmsg("invalid connection type \"%s\"",
1055  token->string),
1056  errcontext("line %d of configuration file \"%s\"",
1057  line_num, HbaFileName)));
1058  *err_msg = psprintf("invalid connection type \"%s\"", token->string);
1059  return NULL;
1060  }
1061 
1062  /* Get the databases. */
1063  field = lnext(tok_line->fields, field);
1064  if (!field)
1065  {
1066  ereport(elevel,
1067  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1068  errmsg("end-of-line before database specification"),
1069  errcontext("line %d of configuration file \"%s\"",
1070  line_num, HbaFileName)));
1071  *err_msg = "end-of-line before database specification";
1072  return NULL;
1073  }
1074  parsedline->databases = NIL;
1075  tokens = lfirst(field);
1076  foreach(tokencell, tokens)
1077  {
1078  parsedline->databases = lappend(parsedline->databases,
1079  copy_hba_token(lfirst(tokencell)));
1080  }
1081 
1082  /* Get the roles. */
1083  field = lnext(tok_line->fields, field);
1084  if (!field)
1085  {
1086  ereport(elevel,
1087  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1088  errmsg("end-of-line before role specification"),
1089  errcontext("line %d of configuration file \"%s\"",
1090  line_num, HbaFileName)));
1091  *err_msg = "end-of-line before role specification";
1092  return NULL;
1093  }
1094  parsedline->roles = NIL;
1095  tokens = lfirst(field);
1096  foreach(tokencell, tokens)
1097  {
1098  parsedline->roles = lappend(parsedline->roles,
1099  copy_hba_token(lfirst(tokencell)));
1100  }
1101 
1102  if (parsedline->conntype != ctLocal)
1103  {
1104  /* Read the IP address field. (with or without CIDR netmask) */
1105  field = lnext(tok_line->fields, field);
1106  if (!field)
1107  {
1108  ereport(elevel,
1109  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1110  errmsg("end-of-line before IP address specification"),
1111  errcontext("line %d of configuration file \"%s\"",
1112  line_num, HbaFileName)));
1113  *err_msg = "end-of-line before IP address specification";
1114  return NULL;
1115  }
1116  tokens = lfirst(field);
1117  if (tokens->length > 1)
1118  {
1119  ereport(elevel,
1120  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1121  errmsg("multiple values specified for host address"),
1122  errhint("Specify one address range per line."),
1123  errcontext("line %d of configuration file \"%s\"",
1124  line_num, HbaFileName)));
1125  *err_msg = "multiple values specified for host address";
1126  return NULL;
1127  }
1128  token = linitial(tokens);
1129 
1130  if (token_is_keyword(token, "all"))
1131  {
1132  parsedline->ip_cmp_method = ipCmpAll;
1133  }
1134  else if (token_is_keyword(token, "samehost"))
1135  {
1136  /* Any IP on this host is allowed to connect */
1137  parsedline->ip_cmp_method = ipCmpSameHost;
1138  }
1139  else if (token_is_keyword(token, "samenet"))
1140  {
1141  /* Any IP on the host's subnets is allowed to connect */
1142  parsedline->ip_cmp_method = ipCmpSameNet;
1143  }
1144  else
1145  {
1146  /* IP and netmask are specified */
1147  parsedline->ip_cmp_method = ipCmpMask;
1148 
1149  /* need a modifiable copy of token */
1150  str = pstrdup(token->string);
1151 
1152  /* Check if it has a CIDR suffix and if so isolate it */
1153  cidr_slash = strchr(str, '/');
1154  if (cidr_slash)
1155  *cidr_slash = '\0';
1156 
1157  /* Get the IP address either way */
1158  hints.ai_flags = AI_NUMERICHOST;
1159  hints.ai_family = AF_UNSPEC;
1160  hints.ai_socktype = 0;
1161  hints.ai_protocol = 0;
1162  hints.ai_addrlen = 0;
1163  hints.ai_canonname = NULL;
1164  hints.ai_addr = NULL;
1165  hints.ai_next = NULL;
1166 
1167  ret = pg_getaddrinfo_all(str, NULL, &hints, &gai_result);
1168  if (ret == 0 && gai_result)
1169  memcpy(&parsedline->addr, gai_result->ai_addr,
1170  gai_result->ai_addrlen);
1171  else if (ret == EAI_NONAME)
1172  parsedline->hostname = str;
1173  else
1174  {
1175  ereport(elevel,
1176  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1177  errmsg("invalid IP address \"%s\": %s",
1178  str, gai_strerror(ret)),
1179  errcontext("line %d of configuration file \"%s\"",
1180  line_num, HbaFileName)));
1181  *err_msg = psprintf("invalid IP address \"%s\": %s",
1182  str, gai_strerror(ret));
1183  if (gai_result)
1184  pg_freeaddrinfo_all(hints.ai_family, gai_result);
1185  return NULL;
1186  }
1187 
1188  pg_freeaddrinfo_all(hints.ai_family, gai_result);
1189 
1190  /* Get the netmask */
1191  if (cidr_slash)
1192  {
1193  if (parsedline->hostname)
1194  {
1195  ereport(elevel,
1196  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1197  errmsg("specifying both host name and CIDR mask is invalid: \"%s\"",
1198  token->string),
1199  errcontext("line %d of configuration file \"%s\"",
1200  line_num, HbaFileName)));
1201  *err_msg = psprintf("specifying both host name and CIDR mask is invalid: \"%s\"",
1202  token->string);
1203  return NULL;
1204  }
1205 
1206  if (pg_sockaddr_cidr_mask(&parsedline->mask, cidr_slash + 1,
1207  parsedline->addr.ss_family) < 0)
1208  {
1209  ereport(elevel,
1210  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1211  errmsg("invalid CIDR mask in address \"%s\"",
1212  token->string),
1213  errcontext("line %d of configuration file \"%s\"",
1214  line_num, HbaFileName)));
1215  *err_msg = psprintf("invalid CIDR mask in address \"%s\"",
1216  token->string);
1217  return NULL;
1218  }
1219  pfree(str);
1220  }
1221  else if (!parsedline->hostname)
1222  {
1223  /* Read the mask field. */
1224  pfree(str);
1225  field = lnext(tok_line->fields, field);
1226  if (!field)
1227  {
1228  ereport(elevel,
1229  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1230  errmsg("end-of-line before netmask specification"),
1231  errhint("Specify an address range in CIDR notation, or provide a separate netmask."),
1232  errcontext("line %d of configuration file \"%s\"",
1233  line_num, HbaFileName)));
1234  *err_msg = "end-of-line before netmask specification";
1235  return NULL;
1236  }
1237  tokens = lfirst(field);
1238  if (tokens->length > 1)
1239  {
1240  ereport(elevel,
1241  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1242  errmsg("multiple values specified for netmask"),
1243  errcontext("line %d of configuration file \"%s\"",
1244  line_num, HbaFileName)));
1245  *err_msg = "multiple values specified for netmask";
1246  return NULL;
1247  }
1248  token = linitial(tokens);
1249 
1250  ret = pg_getaddrinfo_all(token->string, NULL,
1251  &hints, &gai_result);
1252  if (ret || !gai_result)
1253  {
1254  ereport(elevel,
1255  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1256  errmsg("invalid IP mask \"%s\": %s",
1257  token->string, gai_strerror(ret)),
1258  errcontext("line %d of configuration file \"%s\"",
1259  line_num, HbaFileName)));
1260  *err_msg = psprintf("invalid IP mask \"%s\": %s",
1261  token->string, gai_strerror(ret));
1262  if (gai_result)
1263  pg_freeaddrinfo_all(hints.ai_family, gai_result);
1264  return NULL;
1265  }
1266 
1267  memcpy(&parsedline->mask, gai_result->ai_addr,
1268  gai_result->ai_addrlen);
1269  pg_freeaddrinfo_all(hints.ai_family, gai_result);
1270 
1271  if (parsedline->addr.ss_family != parsedline->mask.ss_family)
1272  {
1273  ereport(elevel,
1274  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1275  errmsg("IP address and mask do not match"),
1276  errcontext("line %d of configuration file \"%s\"",
1277  line_num, HbaFileName)));
1278  *err_msg = "IP address and mask do not match";
1279  return NULL;
1280  }
1281  }
1282  }
1283  } /* != ctLocal */
1284 
1285  /* Get the authentication method */
1286  field = lnext(tok_line->fields, field);
1287  if (!field)
1288  {
1289  ereport(elevel,
1290  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1291  errmsg("end-of-line before authentication method"),
1292  errcontext("line %d of configuration file \"%s\"",
1293  line_num, HbaFileName)));
1294  *err_msg = "end-of-line before authentication method";
1295  return NULL;
1296  }
1297  tokens = lfirst(field);
1298  if (tokens->length > 1)
1299  {
1300  ereport(elevel,
1301  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1302  errmsg("multiple values specified for authentication type"),
1303  errhint("Specify exactly one authentication type per line."),
1304  errcontext("line %d of configuration file \"%s\"",
1305  line_num, HbaFileName)));
1306  *err_msg = "multiple values specified for authentication type";
1307  return NULL;
1308  }
1309  token = linitial(tokens);
1310 
1311  unsupauth = NULL;
1312  if (strcmp(token->string, "trust") == 0)
1313  parsedline->auth_method = uaTrust;
1314  else if (strcmp(token->string, "ident") == 0)
1315  parsedline->auth_method = uaIdent;
1316  else if (strcmp(token->string, "peer") == 0)
1317  parsedline->auth_method = uaPeer;
1318  else if (strcmp(token->string, "password") == 0)
1319  parsedline->auth_method = uaPassword;
1320  else if (strcmp(token->string, "gss") == 0)
1321 #ifdef ENABLE_GSS
1322  parsedline->auth_method = uaGSS;
1323 #else
1324  unsupauth = "gss";
1325 #endif
1326  else if (strcmp(token->string, "sspi") == 0)
1327 #ifdef ENABLE_SSPI
1328  parsedline->auth_method = uaSSPI;
1329 #else
1330  unsupauth = "sspi";
1331 #endif
1332  else if (strcmp(token->string, "reject") == 0)
1333  parsedline->auth_method = uaReject;
1334  else if (strcmp(token->string, "md5") == 0)
1335  {
1336  if (Db_user_namespace)
1337  {
1338  ereport(elevel,
1339  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1340  errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled"),
1341  errcontext("line %d of configuration file \"%s\"",
1342  line_num, HbaFileName)));
1343  *err_msg = "MD5 authentication is not supported when \"db_user_namespace\" is enabled";
1344  return NULL;
1345  }
1346  parsedline->auth_method = uaMD5;
1347  }
1348  else if (strcmp(token->string, "scram-sha-256") == 0)
1349  parsedline->auth_method = uaSCRAM;
1350  else if (strcmp(token->string, "pam") == 0)
1351 #ifdef USE_PAM
1352  parsedline->auth_method = uaPAM;
1353 #else
1354  unsupauth = "pam";
1355 #endif
1356  else if (strcmp(token->string, "bsd") == 0)
1357 #ifdef USE_BSD_AUTH
1358  parsedline->auth_method = uaBSD;
1359 #else
1360  unsupauth = "bsd";
1361 #endif
1362  else if (strcmp(token->string, "ldap") == 0)
1363 #ifdef USE_LDAP
1364  parsedline->auth_method = uaLDAP;
1365 #else
1366  unsupauth = "ldap";
1367 #endif
1368  else if (strcmp(token->string, "cert") == 0)
1369 #ifdef USE_SSL
1370  parsedline->auth_method = uaCert;
1371 #else
1372  unsupauth = "cert";
1373 #endif
1374  else if (strcmp(token->string, "radius") == 0)
1375  parsedline->auth_method = uaRADIUS;
1376  else
1377  {
1378  ereport(elevel,
1379  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1380  errmsg("invalid authentication method \"%s\"",
1381  token->string),
1382  errcontext("line %d of configuration file \"%s\"",
1383  line_num, HbaFileName)));
1384  *err_msg = psprintf("invalid authentication method \"%s\"",
1385  token->string);
1386  return NULL;
1387  }
1388 
1389  if (unsupauth)
1390  {
1391  ereport(elevel,
1392  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1393  errmsg("invalid authentication method \"%s\": not supported by this build",
1394  token->string),
1395  errcontext("line %d of configuration file \"%s\"",
1396  line_num, HbaFileName)));
1397  *err_msg = psprintf("invalid authentication method \"%s\": not supported by this build",
1398  token->string);
1399  return NULL;
1400  }
1401 
1402  /*
1403  * XXX: When using ident on local connections, change it to peer, for
1404  * backwards compatibility.
1405  */
1406  if (parsedline->conntype == ctLocal &&
1407  parsedline->auth_method == uaIdent)
1408  parsedline->auth_method = uaPeer;
1409 
1410  /* Invalid authentication combinations */
1411  if (parsedline->conntype == ctLocal &&
1412  parsedline->auth_method == uaGSS)
1413  {
1414  ereport(elevel,
1415  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1416  errmsg("gssapi authentication is not supported on local sockets"),
1417  errcontext("line %d of configuration file \"%s\"",
1418  line_num, HbaFileName)));
1419  *err_msg = "gssapi authentication is not supported on local sockets";
1420  return NULL;
1421  }
1422  if (parsedline->conntype == ctHostGSS &&
1423  parsedline->auth_method != uaGSS &&
1424  parsedline->auth_method != uaReject &&
1425  parsedline->auth_method != uaTrust)
1426  {
1427  ereport(elevel,
1428  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1429  errmsg("GSSAPI encryption only supports gss, trust, or reject authentication"),
1430  errcontext("line %d of configuration file \"%s\"",
1431  line_num, HbaFileName)));
1432  *err_msg = "GSSAPI encryption only supports gss, trust, or reject authentication";
1433  return NULL;
1434  }
1435 
1436  if (parsedline->conntype != ctLocal &&
1437  parsedline->auth_method == uaPeer)
1438  {
1439  ereport(elevel,
1440  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1441  errmsg("peer authentication is only supported on local sockets"),
1442  errcontext("line %d of configuration file \"%s\"",
1443  line_num, HbaFileName)));
1444  *err_msg = "peer authentication is only supported on local sockets";
1445  return NULL;
1446  }
1447 
1448  /*
1449  * SSPI authentication can never be enabled on ctLocal connections,
1450  * because it's only supported on Windows, where ctLocal isn't supported.
1451  */
1452 
1453 
1454  if (parsedline->conntype != ctHostSSL &&
1455  parsedline->auth_method == uaCert)
1456  {
1457  ereport(elevel,
1458  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1459  errmsg("cert authentication is only supported on hostssl connections"),
1460  errcontext("line %d of configuration file \"%s\"",
1461  line_num, HbaFileName)));
1462  *err_msg = "cert authentication is only supported on hostssl connections";
1463  return NULL;
1464  }
1465 
1466  /*
1467  * For GSS and SSPI, set the default value of include_realm to true.
1468  * Having include_realm set to false is dangerous in multi-realm
1469  * situations and is generally considered bad practice. We keep the
1470  * capability around for backwards compatibility, but we might want to
1471  * remove it at some point in the future. Users who still need to strip
1472  * the realm off would be better served by using an appropriate regex in a
1473  * pg_ident.conf mapping.
1474  */
1475  if (parsedline->auth_method == uaGSS ||
1476  parsedline->auth_method == uaSSPI)
1477  parsedline->include_realm = true;
1478 
1479  /*
1480  * For SSPI, include_realm defaults to the SAM-compatible domain (aka
1481  * NetBIOS name) and user names instead of the Kerberos principal name for
1482  * compatibility.
1483  */
1484  if (parsedline->auth_method == uaSSPI)
1485  {
1486  parsedline->compat_realm = true;
1487  parsedline->upn_username = false;
1488  }
1489 
1490  /* Parse remaining arguments */
1491  while ((field = lnext(tok_line->fields, field)) != NULL)
1492  {
1493  tokens = lfirst(field);
1494  foreach(tokencell, tokens)
1495  {
1496  char *val;
1497 
1498  token = lfirst(tokencell);
1499 
1500  str = pstrdup(token->string);
1501  val = strchr(str, '=');
1502  if (val == NULL)
1503  {
1504  /*
1505  * Got something that's not a name=value pair.
1506  */
1507  ereport(elevel,
1508  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1509  errmsg("authentication option not in name=value format: %s", token->string),
1510  errcontext("line %d of configuration file \"%s\"",
1511  line_num, HbaFileName)));
1512  *err_msg = psprintf("authentication option not in name=value format: %s",
1513  token->string);
1514  return NULL;
1515  }
1516 
1517  *val++ = '\0'; /* str now holds "name", val holds "value" */
1518  if (!parse_hba_auth_opt(str, val, parsedline, elevel, err_msg))
1519  /* parse_hba_auth_opt already logged the error message */
1520  return NULL;
1521  pfree(str);
1522  }
1523  }
1524 
1525  /*
1526  * Check if the selected authentication method has any mandatory arguments
1527  * that are not set.
1528  */
1529  if (parsedline->auth_method == uaLDAP)
1530  {
1531 #ifndef HAVE_LDAP_INITIALIZE
1532  /* Not mandatory for OpenLDAP, because it can use DNS SRV records */
1533  MANDATORY_AUTH_ARG(parsedline->ldapserver, "ldapserver", "ldap");
1534 #endif
1535 
1536  /*
1537  * LDAP can operate in two modes: either with a direct bind, using
1538  * ldapprefix and ldapsuffix, or using a search+bind, using
1539  * ldapbasedn, ldapbinddn, ldapbindpasswd and one of
1540  * ldapsearchattribute or ldapsearchfilter. Disallow mixing these
1541  * parameters.
1542  */
1543  if (parsedline->ldapprefix || parsedline->ldapsuffix)
1544  {
1545  if (parsedline->ldapbasedn ||
1546  parsedline->ldapbinddn ||
1547  parsedline->ldapbindpasswd ||
1548  parsedline->ldapsearchattribute ||
1549  parsedline->ldapsearchfilter)
1550  {
1551  ereport(elevel,
1552  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1553  errmsg("cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix"),
1554  errcontext("line %d of configuration file \"%s\"",
1555  line_num, HbaFileName)));
1556  *err_msg = "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix";
1557  return NULL;
1558  }
1559  }
1560  else if (!parsedline->ldapbasedn)
1561  {
1562  ereport(elevel,
1563  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1564  errmsg("authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set"),
1565  errcontext("line %d of configuration file \"%s\"",
1566  line_num, HbaFileName)));
1567  *err_msg = "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set";
1568  return NULL;
1569  }
1570 
1571  /*
1572  * When using search+bind, you can either use a simple attribute
1573  * (defaulting to "uid") or a fully custom search filter. You can't
1574  * do both.
1575  */
1576  if (parsedline->ldapsearchattribute && parsedline->ldapsearchfilter)
1577  {
1578  ereport(elevel,
1579  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1580  errmsg("cannot use ldapsearchattribute together with ldapsearchfilter"),
1581  errcontext("line %d of configuration file \"%s\"",
1582  line_num, HbaFileName)));
1583  *err_msg = "cannot use ldapsearchattribute together with ldapsearchfilter";
1584  return NULL;
1585  }
1586  }
1587 
1588  if (parsedline->auth_method == uaRADIUS)
1589  {
1590  MANDATORY_AUTH_ARG(parsedline->radiusservers, "radiusservers", "radius");
1591  MANDATORY_AUTH_ARG(parsedline->radiussecrets, "radiussecrets", "radius");
1592 
1593  if (list_length(parsedline->radiusservers) < 1)
1594  {
1595  ereport(LOG,
1596  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1597  errmsg("list of RADIUS servers cannot be empty"),
1598  errcontext("line %d of configuration file \"%s\"",
1599  line_num, HbaFileName)));
1600  return NULL;
1601  }
1602 
1603  if (list_length(parsedline->radiussecrets) < 1)
1604  {
1605  ereport(LOG,
1606  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1607  errmsg("list of RADIUS secrets cannot be empty"),
1608  errcontext("line %d of configuration file \"%s\"",
1609  line_num, HbaFileName)));
1610  return NULL;
1611  }
1612 
1613  /*
1614  * Verify length of option lists - each can be 0 (except for secrets,
1615  * but that's already checked above), 1 (use the same value
1616  * everywhere) or the same as the number of servers.
1617  */
1618  if (!verify_option_list_length(parsedline->radiussecrets,
1619  "RADIUS secrets",
1620  parsedline->radiusservers,
1621  "RADIUS servers",
1622  line_num))
1623  return NULL;
1624  if (!verify_option_list_length(parsedline->radiusports,
1625  "RADIUS ports",
1626  parsedline->radiusservers,
1627  "RADIUS servers",
1628  line_num))
1629  return NULL;
1631  "RADIUS identifiers",
1632  parsedline->radiusservers,
1633  "RADIUS servers",
1634  line_num))
1635  return NULL;
1636  }
1637 
1638  /*
1639  * Enforce any parameters implied by other settings.
1640  */
1641  if (parsedline->auth_method == uaCert)
1642  {
1643  parsedline->clientcert = clientCertCA;
1644  }
1645 
1646  return parsedline;
1647 }
List * databases
Definition: hba.h:75
Definition: hba.h:70
#define NIL
Definition: pg_list.h:65
Definition: hba.h:30
bool EnableSSL
Definition: postmaster.c:236
char * ldapserver
Definition: hba.h:88
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
Definition: ip.c:88
struct sockaddr_storage mask
Definition: hba.h:78
int errhint(const char *fmt,...)
Definition: elog.c:1069
Definition: hba.h:38
char * ldapbasedn
Definition: hba.h:94
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
Definition: hba.h:32
static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg)
Definition: hba.c:1678
Definition: hba.h:47
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
Definition: hba.h:35
int errcode(int sqlerrcode)
Definition: elog.c:608
#define LOG
Definition: elog.h:26
#define AI_NUMERICHOST
Definition: getaddrinfo.h:73
List * radiussecrets
Definition: hba.h:105
#define gai_strerror
Definition: getaddrinfo.h:146
char * ldapsuffix
Definition: hba.h:97
char * HbaFileName
Definition: guc.c:530
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
Definition: ip.c:57
Definition: hba.h:34
Definition: hba.h:31
ConnType conntype
Definition: hba.h:74
void pfree(void *pointer)
Definition: mcxt.c:1056
Definition: hba.h:57
static bool verify_option_list_length(List *options, const char *optionname, List *masters, const char *mastername, int line_num)
Definition: hba.c:1651
#define linitial(l)
Definition: pg_list.h:195
Definition: hba.h:39
int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
Definition: ifaddr.c:115
struct sockaddr_storage addr
Definition: hba.h:77
Definition: hba.h:59
int line_num
Definition: hba.c:92
List * radiusports
Definition: hba.h:109
Definition: hba.h:27
List * radiusservers
Definition: hba.h:103
bool include_realm
Definition: hba.h:100
Definition: hba.h:29
bool Db_user_namespace
Definition: postmaster.c:243
char * err_msg
Definition: hba.c:94
Definition: hba.c:75
char * ldapbinddn
Definition: hba.h:90
#define EAI_NONAME
Definition: getaddrinfo.h:34
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
int linenumber
Definition: hba.h:72
#define MANDATORY_AUTH_ARG(argvar, argname, authname)
Definition: hba.c:880
char * ldapbindpasswd
Definition: hba.h:91
List * fields
Definition: hba.c:91
#define ereport(elevel, rest)
Definition: elog.h:141
char * ldapprefix
Definition: hba.h:96
Definition: hba.h:55
List * lappend(List *list, void *datum)
Definition: list.c:322
static int elevel
Definition: vacuumlazy.c:143
Definition: hba.h:33
Definition: hba.h:50
void * palloc0(Size size)
Definition: mcxt.c:980
char * hostname
Definition: hba.h:80
char * string
Definition: hba.c:77
List * radiusidentifiers
Definition: hba.h:107
Definition: hba.h:37
List * roles
Definition: hba.h:76
#define Assert(condition)
Definition: c.h:739
#define lfirst(lc)
Definition: pg_list.h:190
char * ldapsearchfilter
Definition: hba.h:93
ClientCertMode clientcert
Definition: hba.h:98
static int list_length(const List *l)
Definition: pg_list.h:169
char * ldapsearchattribute
Definition: hba.h:92
int length
Definition: pg_list.h:53
char * rawline
Definition: hba.h:73
static HbaToken * copy_hba_token(HbaToken *in)
Definition: hba.c:307
bool upn_username
Definition: hba.h:102
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define token_is_keyword(t, k)
Definition: hba.c:68
#define errcontext
Definition: elog.h:183
size_t ai_addrlen
Definition: getaddrinfo.h:104
char * raw_line
Definition: hba.c:93
IPCompareMethod ip_cmp_method
Definition: hba.h:79
Definition: pg_list.h:50
Definition: hba.h:36
bool compat_realm
Definition: hba.h:101
long val
Definition: informix.c:664
Definition: hba.h:56
Definition: hba.h:40
UserAuth auth_method
Definition: hba.h:81
struct sockaddr * ai_addr
Definition: getaddrinfo.h:105

◆ parse_ident_line()

static IdentLine* parse_ident_line ( TokenizedLine tok_line)
static

Definition at line 2711 of file hba.c.

References Assert, ereport, errcode(), errmsg(), TokenizedLine::fields, IDENT_FIELD_ABSENT, IDENT_MULTI_VALUE, IdentLine::ident_user, lfirst, TokenizedLine::line_num, IdentLine::linenumber, linitial, list_head(), lnext(), LOG, NIL, palloc(), palloc0(), pfree(), pg_mb2wchar_with_len(), pg_regcomp(), pg_regerror(), IdentLine::pg_role, pstrdup(), IdentLine::re, REG_ADVANCED, HbaToken::string, and IdentLine::usermap.

Referenced by load_ident().

2712 {
2713  int line_num = tok_line->line_num;
2714  ListCell *field;
2715  List *tokens;
2716  HbaToken *token;
2717  IdentLine *parsedline;
2718 
2719  Assert(tok_line->fields != NIL);
2720  field = list_head(tok_line->fields);
2721 
2722  parsedline = palloc0(sizeof(IdentLine));
2723  parsedline->linenumber = line_num;
2724 
2725  /* Get the map token (must exist) */
2726  tokens = lfirst(field);
2727  IDENT_MULTI_VALUE(tokens);
2728  token = linitial(tokens);
2729  parsedline->usermap = pstrdup(token->string);
2730 
2731  /* Get the ident user token */
2732  field = lnext(tok_line->fields, field);
2733  IDENT_FIELD_ABSENT(field);
2734  tokens = lfirst(field);
2735  IDENT_MULTI_VALUE(tokens);
2736  token = linitial(tokens);
2737  parsedline->ident_user = pstrdup(token->string);
2738 
2739  /* Get the PG rolename token */
2740  field = lnext(tok_line->fields, field);
2741  IDENT_FIELD_ABSENT(field);
2742  tokens = lfirst(field);
2743  IDENT_MULTI_VALUE(tokens);
2744  token = linitial(tokens);
2745  parsedline->pg_role = pstrdup(token->string);
2746 
2747  if (parsedline->ident_user[0] == '/')
2748  {
2749  /*
2750  * When system username starts with a slash, treat it as a regular
2751  * expression. Pre-compile it.
2752  */
2753  int r;
2754  pg_wchar *wstr;
2755  int wlen;
2756 
2757  wstr = palloc((strlen(parsedline->ident_user + 1) + 1) * sizeof(pg_wchar));
2758  wlen = pg_mb2wchar_with_len(parsedline->ident_user + 1,
2759  wstr, strlen(parsedline->ident_user + 1));
2760 
2761  r = pg_regcomp(&parsedline->re, wstr, wlen, REG_ADVANCED, C_COLLATION_OID);
2762  if (r)
2763  {
2764  char errstr[100];
2765 
2766  pg_regerror(r, &parsedline->re, errstr, sizeof(errstr));
2767  ereport(LOG,
2768  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
2769  errmsg("invalid regular expression \"%s\": %s",
2770  parsedline->ident_user + 1, errstr)));
2771 
2772  pfree(wstr);
2773  return NULL;
2774  }
2775  pfree(wstr);
2776  }
2777 
2778  return parsedline;
2779 }
#define NIL
Definition: pg_list.h:65
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
regex_t re
Definition: hba.h:120
char * pstrdup(const char *in)
Definition: mcxt.c:1186
int errcode(int sqlerrcode)
Definition: elog.c:608
#define LOG
Definition: elog.h:26
int pg_regcomp(regex_t *re, const chr *string, size_t len, int flags, Oid collation)
Definition: regcomp.c:313
#define IDENT_FIELD_ABSENT(field)
Definition: hba.c:908
int linenumber
Definition: hba.h:115
void pfree(void *pointer)
Definition: mcxt.c:1056
#define linitial(l)
Definition: pg_list.h:195
int line_num
Definition: hba.c:92
char * usermap
Definition: hba.h:117
Definition: hba.c:75
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
#define REG_ADVANCED
Definition: regex.h:103
List * fields
Definition: hba.c:91
#define ereport(elevel, rest)
Definition: elog.h:141
unsigned int pg_wchar
Definition: mbprint.c:31
#define IDENT_MULTI_VALUE(tokens)
Definition: hba.c:919
void * palloc0(Size size)
Definition: mcxt.c:980
char * string
Definition: hba.c:77
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:765
#define Assert(condition)
Definition: c.h:739
#define lfirst(lc)
Definition: pg_list.h:190
Definition: hba.h:113
char * ident_user
Definition: hba.h:118
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: pg_list.h:50
char * pg_role
Definition: hba.h:119

◆ pg_hba_file_rules()

Datum pg_hba_file_rules ( PG_FUNCTION_ARGS  )

Definition at line 2648 of file hba.c.

References ReturnSetInfo::allowedModes, ReturnSetInfo::econtext, ExprContext::ecxt_per_query_memory, elog, ereport, errcode(), errmsg(), ERROR, fill_hba_view(), get_call_result_type(), IsA, MemoryContextSwitchTo(), PG_RETURN_NULL, ReturnSetInfo::returnMode, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, SFRM_Materialize_Random, tuplestore_begin_heap(), TYPEFUNC_COMPOSITE, and work_mem.

2649 {
2650  Tuplestorestate *tuple_store;
2651  TupleDesc tupdesc;
2652  MemoryContext old_cxt;
2653  ReturnSetInfo *rsi;
2654 
2655  /*
2656  * We must use the Materialize mode to be safe against HBA file changes
2657  * while the cursor is open. It's also more efficient than having to look
2658  * up our current position in the parsed list every time.
2659  */
2660  rsi = (ReturnSetInfo *) fcinfo->resultinfo;
2661 
2662  /* Check to see if caller supports us returning a tuplestore */
2663  if (rsi == NULL || !IsA(rsi, ReturnSetInfo))
2664  ereport(ERROR,
2665  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2666  errmsg("set-valued function called in context that cannot accept a set")));
2667  if (!(rsi->allowedModes & SFRM_Materialize))
2668  ereport(ERROR,
2669  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2670  errmsg("materialize mode required, but it is not " \
2671  "allowed in this context")));
2672 
2674 
2675  /* Build a tuple descriptor for our result type */
2676  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
2677  elog(ERROR, "return type must be a row type");
2678 
2679  /* Build tuplestore to hold the result rows */
2681 
2682  tuple_store =
2684  false, work_mem);
2685  rsi->setDesc = tupdesc;
2686  rsi->setResult = tuple_store;
2687 
2688  MemoryContextSwitchTo(old_cxt);
2689 
2690  /* Fill the tuplestore */
2691  fill_hba_view(tuple_store, tupdesc);
2692 
2693  PG_RETURN_NULL();
2694 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
Definition: hba.c:2594
int work_mem
Definition: globals.c:121
int allowedModes
Definition: execnodes.h:302
SetFunctionReturnMode returnMode
Definition: execnodes.h:304
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:230
Tuplestorestate * setResult
Definition: execnodes.h:307
ExprContext * econtext
Definition: execnodes.h:300
TupleDesc setDesc
Definition: execnodes.h:308
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_isblank()

bool pg_isblank ( const char  c)

Definition at line 160 of file hba.c.

Referenced by interpret_ident_response(), and next_token().

161 {
162  return c == ' ' || c == '\t' || c == '\r';
163 }
char * c

◆ tokenize_file()

static MemoryContext tokenize_file ( const char *  filename,
FILE *  file,
List **  tok_lines,
int  elevel 
)
static

Definition at line 470 of file hba.c.

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, CurrentMemoryContext, ereport, TokenizedLine::err_msg, errcode(), errcode_for_file_access(), errcontext, errmsg(), TokenizedLine::fields, lappend(), TokenizedLine::line_num, MAX_LINE, MemoryContextSwitchTo(), next_field_expand(), NIL, palloc(), psprintf(), pstrdup(), TokenizedLine::raw_line, and strerror.

Referenced by fill_hba_view(), load_hba(), load_ident(), and tokenize_inc_file().

471 {
472  int line_number = 1;
473  MemoryContext linecxt;
474  MemoryContext oldcxt;
475 
477  "tokenize_file",
479  oldcxt = MemoryContextSwitchTo(linecxt);
480 
481  *tok_lines = NIL;
482 
483  while (!feof(file) && !ferror(file))
484  {
485  char rawline[MAX_LINE];
486  char *lineptr;
487  List *current_line = NIL;
488  char *err_msg = NULL;
489 
490  if (!fgets(rawline, sizeof(rawline), file))
491  {
492  int save_errno = errno;
493 
494  if (!ferror(file))
495  break; /* normal EOF */
496  /* I/O error! */
497  ereport(elevel,
499  errmsg("could not read file \"%s\": %m", filename)));
500  err_msg = psprintf("could not read file \"%s\": %s",
501  filename, strerror(save_errno));
502  rawline[0] = '\0';
503  }
504  if (strlen(rawline) == MAX_LINE - 1)
505  {
506  /* Line too long! */
507  ereport(elevel,
508  (errcode(ERRCODE_CONFIG_FILE_ERROR),
509  errmsg("authentication file line too long"),
510  errcontext("line %d of configuration file \"%s\"",
511  line_number, filename)));
512  err_msg = "authentication file line too long";
513  }
514 
515  /* Strip trailing linebreak from rawline */
516  lineptr = rawline + strlen(rawline) - 1;
517  while (lineptr >= rawline && (*lineptr == '\n' || *lineptr == '\r'))
518  *lineptr-- = '\0';
519 
520  /* Parse fields */
521  lineptr = rawline;
522  while (*lineptr && err_msg == NULL)
523  {
524  List *current_field;
525 
526  current_field = next_field_expand(filename, &lineptr,
527  elevel, &err_msg);
528  /* add field to line, unless we are at EOL or comment start */
529  if (current_field != NIL)
530  current_line = lappend(current_line, current_field);
531  }
532 
533  /* Reached EOL; emit line to TokenizedLine list unless it's boring */
534  if (current_line != NIL || err_msg != NULL)
535  {
536  TokenizedLine *tok_line;
537 
538  tok_line = (TokenizedLine *) palloc(sizeof(TokenizedLine));
539  tok_line->fields = current_line;
540  tok_line->line_num = line_number;
541  tok_line->raw_line = pstrdup(rawline);
542  tok_line->err_msg = err_msg;
543  *tok_lines = lappend(*tok_lines, tok_line);
544  }
545 
546  line_number++;
547  }
548 
549  MemoryContextSwitchTo(oldcxt);
550 
551  return linecxt;
552 }
#define NIL
Definition: pg_list.h:65
#define AllocSetContextCreate
Definition: memutils.h:170
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:202
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:608
int line_num
Definition: hba.c:92
char * err_msg
Definition: hba.c:94
int errcode_for_file_access(void)
Definition: elog.c:631
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
List * fields
Definition: hba.c:91
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:322
#define MAX_LINE
Definition: hba.c:57
static int elevel
Definition: vacuumlazy.c:143
#define strerror
Definition: port.h:205
static char * filename
Definition: pg_dumpall.c:90
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define errcontext
Definition: elog.h:183
char * raw_line
Definition: hba.c:93
Definition: pg_list.h:50
static List * next_field_expand(const char *filename, char **lineptr, int elevel, char **err_msg)
Definition: hba.c:330

◆ tokenize_inc_file()

static List * tokenize_inc_file ( List tokens,
const char *  outer_filename,
const char *  inc_filename,
int  elevel,
char **  err_msg 
)
static

Definition at line 372 of file hba.c.

References AllocateFile(), canonicalize_path(), copy_hba_token(), ereport, TokenizedLine::err_msg, errcode_for_file_access(), errmsg(), TokenizedLine::fields, FreeFile(), get_parent_directory(), is_absolute_path, join_path_components(), lappend(), lfirst, MemoryContextDelete(), palloc(), pfree(), psprintf(), pstrdup(), strerror, and tokenize_file().

Referenced by next_field_expand().

377 {
378  char *inc_fullname;
379  FILE *inc_file;
380  List *inc_lines;
381  ListCell *inc_line;
382  MemoryContext linecxt;
383 
384  if (is_absolute_path(inc_filename))
385  {
386  /* absolute path is taken as-is */
387  inc_fullname = pstrdup(inc_filename);
388  }
389  else
390  {
391  /* relative path is relative to dir of calling file */
392  inc_fullname = (char *) palloc(strlen(outer_filename) + 1 +
393  strlen(inc_filename) + 1);
394  strcpy(inc_fullname, outer_filename);
395  get_parent_directory(inc_fullname);
396  join_path_components(inc_fullname, inc_fullname, inc_filename);
397  canonicalize_path(inc_fullname);
398  }
399 
400  inc_file = AllocateFile(inc_fullname, "r");
401  if (inc_file == NULL)
402  {
403  int save_errno = errno;
404 
405  ereport(elevel,
407  errmsg("could not open secondary authentication file \"@%s\" as \"%s\": %m",
408  inc_filename, inc_fullname)));
409  *err_msg = psprintf("could not open secondary authentication file \"@%s\" as \"%s\": %s",
410  inc_filename, inc_fullname, strerror(save_errno));
411  pfree(inc_fullname);
412  return tokens;
413  }
414 
415  /* There is possible recursion here if the file contains @ */
416  linecxt = tokenize_file(inc_fullname, inc_file, &inc_lines, elevel);
417 
418  FreeFile(inc_file);
419  pfree(inc_fullname);
420 
421  /* Copy all tokens found in the file and append to the tokens list */
422  foreach(inc_line, inc_lines)
423  {
424  TokenizedLine *tok_line = (TokenizedLine *) lfirst(inc_line);
425  ListCell *inc_field;
426 
427  /* If any line has an error, propagate that up to caller */
428  if (tok_line->err_msg)
429  {
430  *err_msg = pstrdup(tok_line->err_msg);
431  break;
432  }
433 
434  foreach(inc_field, tok_line->fields)
435  {
436  List *inc_tokens = lfirst(inc_field);
437  ListCell *inc_token;
438 
439  foreach(inc_token, inc_tokens)
440  {
441  HbaToken *token = lfirst(inc_token);
442 
443  tokens = lappend(tokens, copy_hba_token(token));
444  }
445  }
446  }
447 
448  MemoryContextDelete(linecxt);
449  return tokens;
450 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void canonicalize_path(char *path)
Definition: path.c:254
void pfree(void *pointer)
Definition: mcxt.c:1056
char * err_msg
Definition: hba.c:94
Definition: hba.c:75
int errcode_for_file_access(void)
Definition: elog.c:631
#define is_absolute_path(filename)
Definition: port.h:86
void get_parent_directory(char *path)
Definition: path.c:854
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2242
List * fields
Definition: hba.c:91
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:322
static int elevel
Definition: vacuumlazy.c:143
#define lfirst(lc)
Definition: pg_list.h:190
#define strerror
Definition: port.h:205
static MemoryContext tokenize_file(const char *filename, FILE *file, List **tok_lines, int elevel)
Definition: hba.c:470
void join_path_components(char *ret_path, const char *head, const char *tail)
Definition: path.c:218
static HbaToken * copy_hba_token(HbaToken *in)
Definition: hba.c:307
int FreeFile(FILE *file)
Definition: fd.c:2441
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: pg_list.h:50

◆ verify_option_list_length()

static bool verify_option_list_length ( List options,
const char *  optionname,
List masters,
const char *  mastername,
int  line_num 
)
static

Definition at line 1651 of file hba.c.

References ereport, errcode(), errcontext, errmsg(), HbaFileName, list_length(), and LOG.

Referenced by parse_hba_line().

1652 {
1653  if (list_length(options) == 0 ||
1654  list_length(options) == 1 ||
1655  list_length(options) == list_length(masters))
1656  return true;
1657 
1658  ereport(LOG,
1659  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1660  errmsg("the number of %s (%d) must be 1 or the same as the number of %s (%d)",
1661  optionname,
1662  list_length(options),
1663  mastername,
1664  list_length(masters)
1665  ),
1666  errcontext("line %d of configuration file \"%s\"",
1667  line_num, HbaFileName)));
1668  return false;
1669 }
int errcode(int sqlerrcode)
Definition: elog.c:608
#define LOG
Definition: elog.h:26
char * HbaFileName
Definition: guc.c:530
#define ereport(elevel, rest)
Definition: elog.h:141
static int list_length(const List *l)
Definition: pg_list.h:169
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define errcontext
Definition: elog.h:183

Variable Documentation

◆ parsed_hba_context

MemoryContext parsed_hba_context = NULL
static

Definition at line 102 of file hba.c.

◆ parsed_hba_lines

List* parsed_hba_lines = NIL
static

Definition at line 101 of file hba.c.

◆ parsed_ident_context

MemoryContext parsed_ident_context = NULL
static

Definition at line 113 of file hba.c.

◆ parsed_ident_lines

List* parsed_ident_lines = NIL
static

Definition at line 112 of file hba.c.

◆ UserAuthName

const char* const UserAuthName[]
static
Initial value:
=
{
"reject",
"implicit reject",
"trust",
"ident",
"password",
"md5",
"scram-sha-256",
"gss",
"sspi",
"pam",
"bsd",
"ldap",
"cert",
"radius",
"peer"
}

Definition at line 121 of file hba.c.

Referenced by fill_hba_line().