LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - hbafuncs.c (source / functions) Coverage Total Hit LBC UBC CBC
Current: b45a8d7d8b306b43f31a002f1b3f1dddc8defeaf vs 8767b449a3a1e75626dfb08f24da54933171d4c5 Lines: 51.4 % 245 126 26 93 126
Current Date: 2025-10-28 08:26:42 +0900 Functions: 85.7 % 7 6 1 6
Baseline: lcov-20251028-005825-baseline Branches: 39.2 % 148 58 10 80 58
Baseline Date: 2025-10-27 06:37:35 +0000 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 68.8 % 16 11 5 11
(360..) days: 50.2 % 229 115 26 88 115
Function coverage date bins:
(360..) days: 85.7 % 7 6 1 6
Branch coverage date bins:
(30,360] days: 50.0 % 12 6 6 6
(360..) days: 38.2 % 136 52 10 74 52

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * hbafuncs.c
                                  4                 :                :  *    Support functions for SQL views of authentication files.
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/backend/utils/adt/hbafuncs.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : #include "postgres.h"
                                 16                 :                : 
                                 17                 :                : #include "access/htup_details.h"
                                 18                 :                : #include "catalog/objectaddress.h"
                                 19                 :                : #include "common/ip.h"
                                 20                 :                : #include "funcapi.h"
                                 21                 :                : #include "libpq/hba.h"
                                 22                 :                : #include "utils/array.h"
                                 23                 :                : #include "utils/builtins.h"
                                 24                 :                : #include "utils/guc.h"
                                 25                 :                : 
                                 26                 :                : 
                                 27                 :                : static ArrayType *get_hba_options(HbaLine *hba);
                                 28                 :                : static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
                                 29                 :                :                           int rule_number, char *filename, int lineno,
                                 30                 :                :                           HbaLine *hba, const char *err_msg);
                                 31                 :                : static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
                                 32                 :                : static void fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
                                 33                 :                :                             int map_number, char *filename, int lineno,
                                 34                 :                :                             IdentLine *ident, const char *err_msg);
                                 35                 :                : static void fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
                                 36                 :                : 
                                 37                 :                : 
                                 38                 :                : /*
                                 39                 :                :  * This macro specifies the maximum number of authentication options
                                 40                 :                :  * that are possible with any given authentication method that is supported.
                                 41                 :                :  * Currently LDAP supports 12, and there are 3 that are not dependent on
                                 42                 :                :  * the auth method here.  It may not actually be possible to set all of them
                                 43                 :                :  * at the same time, but we'll set the macro value high enough to be
                                 44                 :                :  * conservative and avoid warnings from static analysis tools.
                                 45                 :                :  */
                                 46                 :                : #define MAX_HBA_OPTIONS 15
                                 47                 :                : 
                                 48                 :                : /*
                                 49                 :                :  * Create a text array listing the options specified in the HBA line.
                                 50                 :                :  * Return NULL if no options are specified.
                                 51                 :                :  */
                                 52                 :                : static ArrayType *
 1314 michael@paquier.xyz        53                 :CBC          31 : get_hba_options(HbaLine *hba)
                                 54                 :                : {
                                 55                 :                :     int         noptions;
                                 56                 :                :     Datum       options[MAX_HBA_OPTIONS];
                                 57                 :                : 
                                 58                 :             31 :     noptions = 0;
                                 59                 :                : 
                                 60   [ +  -  -  + ]:             31 :     if (hba->auth_method == uaGSS || hba->auth_method == uaSSPI)
                                 61                 :                :     {
 1314 michael@paquier.xyz        62         [ #  # ]:UBC           0 :         if (hba->include_realm)
                                 63                 :              0 :             options[noptions++] =
                                 64                 :              0 :                 CStringGetTextDatum("include_realm=true");
                                 65                 :                : 
                                 66         [ #  # ]:              0 :         if (hba->krb_realm)
                                 67                 :              0 :             options[noptions++] =
                                 68                 :              0 :                 CStringGetTextDatum(psprintf("krb_realm=%s", hba->krb_realm));
                                 69                 :                :     }
                                 70                 :                : 
 1314 michael@paquier.xyz        71         [ -  + ]:CBC          31 :     if (hba->usermap)
 1314 michael@paquier.xyz        72                 :UBC           0 :         options[noptions++] =
                                 73                 :              0 :             CStringGetTextDatum(psprintf("map=%s", hba->usermap));
                                 74                 :                : 
 1314 michael@paquier.xyz        75         [ -  + ]:CBC          31 :     if (hba->clientcert != clientCertOff)
 1314 michael@paquier.xyz        76                 :UBC           0 :         options[noptions++] =
                                 77         [ #  # ]:              0 :             CStringGetTextDatum(psprintf("clientcert=%s", (hba->clientcert == clientCertCA) ? "verify-ca" : "verify-full"));
                                 78                 :                : 
 1314 michael@paquier.xyz        79         [ -  + ]:CBC          31 :     if (hba->pamservice)
 1314 michael@paquier.xyz        80                 :UBC           0 :         options[noptions++] =
                                 81                 :              0 :             CStringGetTextDatum(psprintf("pamservice=%s", hba->pamservice));
                                 82                 :                : 
 1314 michael@paquier.xyz        83         [ -  + ]:CBC          31 :     if (hba->auth_method == uaLDAP)
                                 84                 :                :     {
 1314 michael@paquier.xyz        85         [ #  # ]:UBC           0 :         if (hba->ldapserver)
                                 86                 :              0 :             options[noptions++] =
                                 87                 :              0 :                 CStringGetTextDatum(psprintf("ldapserver=%s", hba->ldapserver));
                                 88                 :                : 
                                 89         [ #  # ]:              0 :         if (hba->ldapport)
                                 90                 :              0 :             options[noptions++] =
                                 91                 :              0 :                 CStringGetTextDatum(psprintf("ldapport=%d", hba->ldapport));
                                 92                 :                : 
  291 dgustafsson@postgres       93         [ #  # ]:              0 :         if (hba->ldapscheme)
                                 94                 :              0 :             options[noptions++] =
                                 95                 :              0 :                 CStringGetTextDatum(psprintf("ldapscheme=%s", hba->ldapscheme));
                                 96                 :                : 
 1314 michael@paquier.xyz        97         [ #  # ]:              0 :         if (hba->ldaptls)
                                 98                 :              0 :             options[noptions++] =
                                 99                 :              0 :                 CStringGetTextDatum("ldaptls=true");
                                100                 :                : 
                                101         [ #  # ]:              0 :         if (hba->ldapprefix)
                                102                 :              0 :             options[noptions++] =
                                103                 :              0 :                 CStringGetTextDatum(psprintf("ldapprefix=%s", hba->ldapprefix));
                                104                 :                : 
                                105         [ #  # ]:              0 :         if (hba->ldapsuffix)
                                106                 :              0 :             options[noptions++] =
                                107                 :              0 :                 CStringGetTextDatum(psprintf("ldapsuffix=%s", hba->ldapsuffix));
                                108                 :                : 
                                109         [ #  # ]:              0 :         if (hba->ldapbasedn)
                                110                 :              0 :             options[noptions++] =
                                111                 :              0 :                 CStringGetTextDatum(psprintf("ldapbasedn=%s", hba->ldapbasedn));
                                112                 :                : 
                                113         [ #  # ]:              0 :         if (hba->ldapbinddn)
                                114                 :              0 :             options[noptions++] =
                                115                 :              0 :                 CStringGetTextDatum(psprintf("ldapbinddn=%s", hba->ldapbinddn));
                                116                 :                : 
                                117         [ #  # ]:              0 :         if (hba->ldapbindpasswd)
                                118                 :              0 :             options[noptions++] =
                                119                 :              0 :                 CStringGetTextDatum(psprintf("ldapbindpasswd=%s",
                                120                 :                :                                              hba->ldapbindpasswd));
                                121                 :                : 
                                122         [ #  # ]:              0 :         if (hba->ldapsearchattribute)
                                123                 :              0 :             options[noptions++] =
                                124                 :              0 :                 CStringGetTextDatum(psprintf("ldapsearchattribute=%s",
                                125                 :                :                                              hba->ldapsearchattribute));
                                126                 :                : 
                                127         [ #  # ]:              0 :         if (hba->ldapsearchfilter)
                                128                 :              0 :             options[noptions++] =
                                129                 :              0 :                 CStringGetTextDatum(psprintf("ldapsearchfilter=%s",
                                130                 :                :                                              hba->ldapsearchfilter));
                                131                 :                : 
                                132         [ #  # ]:              0 :         if (hba->ldapscope)
                                133                 :              0 :             options[noptions++] =
                                134                 :              0 :                 CStringGetTextDatum(psprintf("ldapscope=%d", hba->ldapscope));
                                135                 :                :     }
                                136                 :                : 
 1314 michael@paquier.xyz       137         [ -  + ]:CBC          31 :     if (hba->auth_method == uaRADIUS)
                                138                 :                :     {
 1314 michael@paquier.xyz       139         [ #  # ]:UBC           0 :         if (hba->radiusservers_s)
                                140                 :              0 :             options[noptions++] =
                                141                 :              0 :                 CStringGetTextDatum(psprintf("radiusservers=%s", hba->radiusservers_s));
                                142                 :                : 
                                143         [ #  # ]:              0 :         if (hba->radiussecrets_s)
                                144                 :              0 :             options[noptions++] =
                                145                 :              0 :                 CStringGetTextDatum(psprintf("radiussecrets=%s", hba->radiussecrets_s));
                                146                 :                : 
                                147         [ #  # ]:              0 :         if (hba->radiusidentifiers_s)
                                148                 :              0 :             options[noptions++] =
                                149                 :              0 :                 CStringGetTextDatum(psprintf("radiusidentifiers=%s", hba->radiusidentifiers_s));
                                150                 :                : 
                                151         [ #  # ]:              0 :         if (hba->radiusports_s)
                                152                 :              0 :             options[noptions++] =
                                153                 :              0 :                 CStringGetTextDatum(psprintf("radiusports=%s", hba->radiusports_s));
                                154                 :                :     }
                                155                 :                : 
  250 dgustafsson@postgres      156         [ +  + ]:CBC          31 :     if (hba->auth_method == uaOAuth)
                                157                 :                :     {
                                158         [ +  - ]:              3 :         if (hba->oauth_issuer)
                                159                 :              3 :             options[noptions++] =
                                160                 :              3 :                 CStringGetTextDatum(psprintf("issuer=%s", hba->oauth_issuer));
                                161                 :                : 
                                162         [ +  - ]:              3 :         if (hba->oauth_scope)
                                163                 :              3 :             options[noptions++] =
                                164                 :              3 :                 CStringGetTextDatum(psprintf("scope=%s", hba->oauth_scope));
                                165                 :                : 
                                166         [ +  - ]:              3 :         if (hba->oauth_validator)
                                167                 :              3 :             options[noptions++] =
                                168                 :              3 :                 CStringGetTextDatum(psprintf("validator=%s", hba->oauth_validator));
                                169                 :                : 
                                170         [ -  + ]:              3 :         if (hba->oauth_skip_usermap)
  250 dgustafsson@postgres      171                 :UBC           0 :             options[noptions++] =
                                172                 :              0 :                 CStringGetTextDatum(psprintf("delegate_ident_mapping=true"));
                                173                 :                :     }
                                174                 :                : 
                                175                 :                :     /* If you add more options, consider increasing MAX_HBA_OPTIONS. */
 1314 michael@paquier.xyz       176         [ -  + ]:CBC          31 :     Assert(noptions <= MAX_HBA_OPTIONS);
                                177                 :                : 
                                178         [ +  + ]:             31 :     if (noptions > 0)
 1215 peter@eisentraut.org      179                 :              3 :         return construct_array_builtin(options, noptions, TEXTOID);
                                180                 :                :     else
 1314 michael@paquier.xyz       181                 :             28 :         return NULL;
                                182                 :                : }
                                183                 :                : 
                                184                 :                : /* Number of columns in pg_hba_file_rules view */
                                185                 :                : #define NUM_PG_HBA_FILE_RULES_ATTS   11
                                186                 :                : 
                                187                 :                : /*
                                188                 :                :  * fill_hba_line
                                189                 :                :  *      Build one row of pg_hba_file_rules view, add it to tuplestore.
                                190                 :                :  *
                                191                 :                :  * tuple_store: where to store data
                                192                 :                :  * tupdesc: tuple descriptor for the view
                                193                 :                :  * rule_number: unique identifier among all valid rules
                                194                 :                :  * filename: configuration file name (must always be valid)
                                195                 :                :  * lineno: line number of configuration file (must always be valid)
                                196                 :                :  * hba: parsed line data (can be NULL, in which case err_msg should be set)
                                197                 :                :  * err_msg: error message (NULL if none)
                                198                 :                :  *
                                199                 :                :  * Note: leaks memory, but we don't care since this is run in a short-lived
                                200                 :                :  * memory context.
                                201                 :                :  */
                                202                 :                : static void
                                203                 :             31 : fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
                                204                 :                :               int rule_number, char *filename, int lineno, HbaLine *hba,
                                205                 :                :               const char *err_msg)
                                206                 :                : {
                                207                 :                :     Datum       values[NUM_PG_HBA_FILE_RULES_ATTS];
                                208                 :                :     bool        nulls[NUM_PG_HBA_FILE_RULES_ATTS];
                                209                 :                :     char        buffer[NI_MAXHOST];
                                210                 :                :     HeapTuple   tuple;
                                211                 :                :     int         index;
                                212                 :                :     ListCell   *lc;
                                213                 :                :     const char *typestr;
                                214                 :                :     const char *addrstr;
                                215                 :                :     const char *maskstr;
                                216                 :                :     ArrayType  *options;
                                217                 :                : 
                                218         [ -  + ]:             31 :     Assert(tupdesc->natts == NUM_PG_HBA_FILE_RULES_ATTS);
                                219                 :                : 
                                220                 :             31 :     memset(values, 0, sizeof(values));
                                221                 :             31 :     memset(nulls, 0, sizeof(nulls));
                                222                 :             31 :     index = 0;
                                223                 :                : 
                                224                 :                :     /* rule_number, nothing on error */
 1098                           225         [ -  + ]:             31 :     if (err_msg)
 1098 michael@paquier.xyz       226                 :UBC           0 :         nulls[index++] = true;
                                227                 :                :     else
 1098 michael@paquier.xyz       228                 :CBC          31 :         values[index++] = Int32GetDatum(rule_number);
                                229                 :                : 
                                230                 :                :     /* file_name */
 1069                           231                 :             31 :     values[index++] = CStringGetTextDatum(filename);
                                232                 :                : 
                                233                 :                :     /* line_number */
 1314                           234                 :             31 :     values[index++] = Int32GetDatum(lineno);
                                235                 :                : 
                                236         [ +  - ]:             31 :     if (hba != NULL)
                                237                 :                :     {
                                238                 :                :         /* type */
                                239                 :                :         /* Avoid a default: case so compiler will warn about missing cases */
                                240                 :             31 :         typestr = NULL;
                                241   [ +  +  -  -  :             31 :         switch (hba->conntype)
                                           -  -  - ]
                                242                 :                :         {
                                243                 :             19 :             case ctLocal:
                                244                 :             19 :                 typestr = "local";
                                245                 :             19 :                 break;
                                246                 :             12 :             case ctHost:
                                247                 :             12 :                 typestr = "host";
                                248                 :             12 :                 break;
 1314 michael@paquier.xyz       249                 :UBC           0 :             case ctHostSSL:
                                250                 :              0 :                 typestr = "hostssl";
                                251                 :              0 :                 break;
                                252                 :              0 :             case ctHostNoSSL:
                                253                 :              0 :                 typestr = "hostnossl";
                                254                 :              0 :                 break;
                                255                 :              0 :             case ctHostGSS:
                                256                 :              0 :                 typestr = "hostgssenc";
                                257                 :              0 :                 break;
                                258                 :              0 :             case ctHostNoGSS:
                                259                 :              0 :                 typestr = "hostnogssenc";
                                260                 :              0 :                 break;
                                261                 :                :         }
 1314 michael@paquier.xyz       262         [ +  - ]:CBC          31 :         if (typestr)
                                263                 :             31 :             values[index++] = CStringGetTextDatum(typestr);
                                264                 :                :         else
 1314 michael@paquier.xyz       265                 :UBC           0 :             nulls[index++] = true;
                                266                 :                : 
                                267                 :                :         /* database */
 1314 michael@paquier.xyz       268         [ +  - ]:CBC          31 :         if (hba->databases)
                                269                 :                :         {
                                270                 :                :             /*
                                271                 :                :              * Flatten AuthToken list to string list.  It might seem that we
                                272                 :                :              * should re-quote any quoted tokens, but that has been rejected
                                273                 :                :              * on the grounds that it makes it harder to compare the array
                                274                 :                :              * elements to other system catalogs.  That makes entries like
                                275                 :                :              * "all" or "samerole" formally ambiguous ... but users who name
                                276                 :                :              * databases/roles that way are inflicting their own pain.
                                277                 :                :              */
                                278                 :             31 :             List       *names = NIL;
                                279                 :                : 
                                280   [ +  -  +  +  :             63 :             foreach(lc, hba->databases)
                                              +  + ]
                                281                 :                :             {
                                282                 :             32 :                 AuthToken  *tok = lfirst(lc);
                                283                 :                : 
                                284                 :             32 :                 names = lappend(names, tok->string);
                                285                 :                :             }
                                286                 :             31 :             values[index++] = PointerGetDatum(strlist_to_textarray(names));
                                287                 :                :         }
                                288                 :                :         else
 1314 michael@paquier.xyz       289                 :UBC           0 :             nulls[index++] = true;
                                290                 :                : 
                                291                 :                :         /* user */
 1314 michael@paquier.xyz       292         [ +  - ]:CBC          31 :         if (hba->roles)
                                293                 :                :         {
                                294                 :                :             /* Flatten AuthToken list to string list; see comment above */
                                295                 :             31 :             List       *roles = NIL;
                                296                 :                : 
                                297   [ +  -  +  +  :             62 :             foreach(lc, hba->roles)
                                              +  + ]
                                298                 :                :             {
                                299                 :             31 :                 AuthToken  *tok = lfirst(lc);
                                300                 :                : 
                                301                 :             31 :                 roles = lappend(roles, tok->string);
                                302                 :                :             }
                                303                 :             31 :             values[index++] = PointerGetDatum(strlist_to_textarray(roles));
                                304                 :                :         }
                                305                 :                :         else
 1314 michael@paquier.xyz       306                 :UBC           0 :             nulls[index++] = true;
                                307                 :                : 
                                308                 :                :         /* address and netmask */
                                309                 :                :         /* Avoid a default: case so compiler will warn about missing cases */
 1314 michael@paquier.xyz       310                 :CBC          31 :         addrstr = maskstr = NULL;
                                311   [ +  -  -  -  :             31 :         switch (hba->ip_cmp_method)
                                                 - ]
                                312                 :                :         {
                                313                 :             31 :             case ipCmpMask:
                                314         [ -  + ]:             31 :                 if (hba->hostname)
                                315                 :                :                 {
 1314 michael@paquier.xyz       316                 :UBC           0 :                     addrstr = hba->hostname;
                                317                 :                :                 }
                                318                 :                :                 else
                                319                 :                :                 {
                                320                 :                :                     /*
                                321                 :                :                      * Note: if pg_getnameinfo_all fails, it'll set buffer to
                                322                 :                :                      * "???", which we want to return.
                                323                 :                :                      */
 1314 michael@paquier.xyz       324         [ +  + ]:CBC          31 :                     if (hba->addrlen > 0)
                                325                 :                :                     {
                                326         [ +  - ]:             12 :                         if (pg_getnameinfo_all(&hba->addr, hba->addrlen,
                                327                 :                :                                                buffer, sizeof(buffer),
                                328                 :                :                                                NULL, 0,
                                329                 :                :                                                NI_NUMERICHOST) == 0)
                                330                 :             12 :                             clean_ipv6_addr(hba->addr.ss_family, buffer);
                                331                 :             12 :                         addrstr = pstrdup(buffer);
                                332                 :                :                     }
                                333         [ +  + ]:             31 :                     if (hba->masklen > 0)
                                334                 :                :                     {
                                335         [ +  - ]:             12 :                         if (pg_getnameinfo_all(&hba->mask, hba->masklen,
                                336                 :                :                                                buffer, sizeof(buffer),
                                337                 :                :                                                NULL, 0,
                                338                 :                :                                                NI_NUMERICHOST) == 0)
                                339                 :             12 :                             clean_ipv6_addr(hba->mask.ss_family, buffer);
                                340                 :             12 :                         maskstr = pstrdup(buffer);
                                341                 :                :                     }
                                342                 :                :                 }
                                343                 :             31 :                 break;
 1314 michael@paquier.xyz       344                 :UBC           0 :             case ipCmpAll:
                                345                 :              0 :                 addrstr = "all";
                                346                 :              0 :                 break;
                                347                 :              0 :             case ipCmpSameHost:
                                348                 :              0 :                 addrstr = "samehost";
                                349                 :              0 :                 break;
                                350                 :              0 :             case ipCmpSameNet:
                                351                 :              0 :                 addrstr = "samenet";
                                352                 :              0 :                 break;
                                353                 :                :         }
 1314 michael@paquier.xyz       354         [ +  + ]:CBC          31 :         if (addrstr)
                                355                 :             12 :             values[index++] = CStringGetTextDatum(addrstr);
                                356                 :                :         else
                                357                 :             19 :             nulls[index++] = true;
                                358         [ +  + ]:             31 :         if (maskstr)
                                359                 :             12 :             values[index++] = CStringGetTextDatum(maskstr);
                                360                 :                :         else
                                361                 :             19 :             nulls[index++] = true;
                                362                 :                : 
                                363                 :                :         /* auth_method */
                                364                 :             31 :         values[index++] = CStringGetTextDatum(hba_authname(hba->auth_method));
                                365                 :                : 
                                366                 :                :         /* options */
                                367                 :             31 :         options = get_hba_options(hba);
                                368         [ +  + ]:             31 :         if (options)
                                369                 :              3 :             values[index++] = PointerGetDatum(options);
                                370                 :                :         else
                                371                 :             28 :             nulls[index++] = true;
                                372                 :                :     }
                                373                 :                :     else
                                374                 :                :     {
                                375                 :                :         /* no parsing result, so set relevant fields to nulls */
 1069 michael@paquier.xyz       376                 :UBC           0 :         memset(&nulls[3], true, (NUM_PG_HBA_FILE_RULES_ATTS - 4) * sizeof(bool));
                                377                 :                :     }
                                378                 :                : 
                                379                 :                :     /* error */
 1314 michael@paquier.xyz       380         [ -  + ]:CBC          31 :     if (err_msg)
 1314 michael@paquier.xyz       381                 :UBC           0 :         values[NUM_PG_HBA_FILE_RULES_ATTS - 1] = CStringGetTextDatum(err_msg);
                                382                 :                :     else
 1314 michael@paquier.xyz       383                 :CBC          31 :         nulls[NUM_PG_HBA_FILE_RULES_ATTS - 1] = true;
                                384                 :                : 
                                385                 :             31 :     tuple = heap_form_tuple(tupdesc, values, nulls);
                                386                 :             31 :     tuplestore_puttuple(tuple_store, tuple);
                                387                 :             31 : }
                                388                 :                : 
                                389                 :                : /*
                                390                 :                :  * fill_hba_view
                                391                 :                :  *      Read the pg_hba.conf file and fill the tuplestore with view records.
                                392                 :                :  */
                                393                 :                : static void
                                394                 :              5 : fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
                                395                 :                : {
                                396                 :                :     FILE       *file;
                                397                 :              5 :     List       *hba_lines = NIL;
                                398                 :                :     ListCell   *line;
 1098                           399                 :              5 :     int         rule_number = 0;
                                400                 :                :     MemoryContext hbacxt;
                                401                 :                :     MemoryContext oldcxt;
                                402                 :                : 
                                403                 :                :     /*
                                404                 :                :      * In the unlikely event that we can't open pg_hba.conf, we throw an
                                405                 :                :      * error, rather than trying to report it via some sort of view entry.
                                406                 :                :      * (Most other error conditions should result in a message in a view
                                407                 :                :      * entry.)
                                408                 :                :      */
 1079                           409                 :              5 :     file = open_auth_file(HbaFileName, ERROR, 0, NULL);
                                410                 :                : 
 1069                           411                 :              5 :     tokenize_auth_file(HbaFileName, file, &hba_lines, DEBUG3, 0);
                                412                 :                : 
                                413                 :                :     /* Now parse all the lines */
 1314                           414                 :              5 :     hbacxt = AllocSetContextCreate(CurrentMemoryContext,
                                415                 :                :                                    "hba parser context",
                                416                 :                :                                    ALLOCSET_SMALL_SIZES);
                                417                 :              5 :     oldcxt = MemoryContextSwitchTo(hbacxt);
                                418   [ +  -  +  +  :             36 :     foreach(line, hba_lines)
                                              +  + ]
                                419                 :                :     {
                                420                 :             31 :         TokenizedAuthLine *tok_line = (TokenizedAuthLine *) lfirst(line);
                                421                 :             31 :         HbaLine    *hbaline = NULL;
                                422                 :                : 
                                423                 :                :         /* don't parse lines that already have errors */
                                424         [ +  - ]:             31 :         if (tok_line->err_msg == NULL)
                                425                 :             31 :             hbaline = parse_hba_line(tok_line, DEBUG3);
                                426                 :                : 
                                427                 :                :         /* No error, set a new rule number */
 1098                           428         [ +  - ]:             31 :         if (tok_line->err_msg == NULL)
                                429                 :             31 :             rule_number++;
                                430                 :                : 
                                431                 :             31 :         fill_hba_line(tuple_store, tupdesc, rule_number,
                                432                 :                :                       tok_line->file_name, tok_line->line_num, hbaline,
 1069                           433                 :             31 :                       tok_line->err_msg);
                                434                 :                :     }
                                435                 :                : 
                                436                 :                :     /* Free tokenizer memory */
                                437                 :              5 :     free_auth_file(file, 0);
                                438                 :                :     /* Free parse_hba_line memory */
 1314                           439                 :              5 :     MemoryContextSwitchTo(oldcxt);
                                440                 :              5 :     MemoryContextDelete(hbacxt);
                                441                 :              5 : }
                                442                 :                : 
                                443                 :                : /*
                                444                 :                :  * pg_hba_file_rules
                                445                 :                :  *
                                446                 :                :  * SQL-accessible set-returning function to return all the entries in the
                                447                 :                :  * pg_hba.conf file.
                                448                 :                :  */
                                449                 :                : Datum
                                450                 :              5 : pg_hba_file_rules(PG_FUNCTION_ARGS)
                                451                 :                : {
                                452                 :                :     ReturnSetInfo *rsi;
                                453                 :                : 
                                454                 :                :     /*
                                455                 :                :      * Build tuplestore to hold the result rows.  We must use the Materialize
                                456                 :                :      * mode to be safe against HBA file changes while the cursor is open. It's
                                457                 :                :      * also more efficient than having to look up our current position in the
                                458                 :                :      * parsed list every time.
                                459                 :                :      */
 1106                           460                 :              5 :     InitMaterializedSRF(fcinfo, 0);
                                461                 :                : 
                                462                 :                :     /* Fill the tuplestore */
 1314                           463                 :              5 :     rsi = (ReturnSetInfo *) fcinfo->resultinfo;
                                464                 :              5 :     fill_hba_view(rsi->setResult, rsi->setDesc);
                                465                 :                : 
                                466                 :              5 :     PG_RETURN_NULL();
                                467                 :                : }
                                468                 :                : 
                                469                 :                : /* Number of columns in pg_ident_file_mappings view */
                                470                 :                : #define NUM_PG_IDENT_FILE_MAPPINGS_ATTS  7
                                471                 :                : 
                                472                 :                : /*
                                473                 :                :  * fill_ident_line: build one row of pg_ident_file_mappings view, add it to
                                474                 :                :  * tuplestore
                                475                 :                :  *
                                476                 :                :  * tuple_store: where to store data
                                477                 :                :  * tupdesc: tuple descriptor for the view
                                478                 :                :  * map_number: unique identifier among all valid maps
                                479                 :                :  * filename: configuration file name (must always be valid)
                                480                 :                :  * lineno: line number of configuration file (must always be valid)
                                481                 :                :  * ident: parsed line data (can be NULL, in which case err_msg should be set)
                                482                 :                :  * err_msg: error message (NULL if none)
                                483                 :                :  *
                                484                 :                :  * Note: leaks memory, but we don't care since this is run in a short-lived
                                485                 :                :  * memory context.
                                486                 :                :  */
                                487                 :                : static void
 1309 michael@paquier.xyz       488                 :LBC         (8) : fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
                                489                 :                :                 int map_number, char *filename, int lineno, IdentLine *ident,
                                490                 :                :                 const char *err_msg)
                                491                 :                : {
                                492                 :                :     Datum       values[NUM_PG_IDENT_FILE_MAPPINGS_ATTS];
                                493                 :                :     bool        nulls[NUM_PG_IDENT_FILE_MAPPINGS_ATTS];
                                494                 :                :     HeapTuple   tuple;
                                495                 :                :     int         index;
                                496                 :                : 
                                497         [ #  # ]:            (8) :     Assert(tupdesc->natts == NUM_PG_IDENT_FILE_MAPPINGS_ATTS);
                                498                 :                : 
                                499                 :            (8) :     memset(values, 0, sizeof(values));
                                500                 :            (8) :     memset(nulls, 0, sizeof(nulls));
                                501                 :            (8) :     index = 0;
                                502                 :                : 
                                503                 :                :     /* map_number, nothing on error */
 1098                           504         [ #  # ]:            (8) :     if (err_msg)
 1098 michael@paquier.xyz       505                 :UBC           0 :         nulls[index++] = true;
                                506                 :                :     else
 1098 michael@paquier.xyz       507                 :LBC         (8) :         values[index++] = Int32GetDatum(map_number);
                                508                 :                : 
                                509                 :                :     /* file_name */
 1069                           510                 :            (8) :     values[index++] = CStringGetTextDatum(filename);
                                511                 :                : 
                                512                 :                :     /* line_number */
 1309                           513                 :            (8) :     values[index++] = Int32GetDatum(lineno);
                                514                 :                : 
                                515         [ #  # ]:            (8) :     if (ident != NULL)
                                516                 :                :     {
                                517                 :            (8) :         values[index++] = CStringGetTextDatum(ident->usermap);
 1020                           518                 :            (8) :         values[index++] = CStringGetTextDatum(ident->system_user->string);
 1016                           519                 :            (8) :         values[index++] = CStringGetTextDatum(ident->pg_user->string);
                                520                 :                :     }
                                521                 :                :     else
                                522                 :                :     {
                                523                 :                :         /* no parsing result, so set relevant fields to nulls */
 1069 michael@paquier.xyz       524                 :UBC           0 :         memset(&nulls[3], true, (NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 4) * sizeof(bool));
                                525                 :                :     }
                                526                 :                : 
                                527                 :                :     /* error */
 1309 michael@paquier.xyz       528         [ #  # ]:LBC         (8) :     if (err_msg)
 1309 michael@paquier.xyz       529                 :UBC           0 :         values[NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 1] = CStringGetTextDatum(err_msg);
                                530                 :                :     else
 1309 michael@paquier.xyz       531                 :LBC         (8) :         nulls[NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 1] = true;
                                532                 :                : 
                                533                 :            (8) :     tuple = heap_form_tuple(tupdesc, values, nulls);
                                534                 :            (8) :     tuplestore_puttuple(tuple_store, tuple);
                                535                 :            (8) : }
                                536                 :                : 
                                537                 :                : /*
                                538                 :                :  * Read the pg_ident.conf file and fill the tuplestore with view records.
                                539                 :                :  */
                                540                 :                : static void
 1309 michael@paquier.xyz       541                 :CBC           3 : fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
                                542                 :                : {
                                543                 :                :     FILE       *file;
                                544                 :              3 :     List       *ident_lines = NIL;
                                545                 :                :     ListCell   *line;
 1098                           546                 :              3 :     int         map_number = 0;
                                547                 :                :     MemoryContext identcxt;
                                548                 :                :     MemoryContext oldcxt;
                                549                 :                : 
                                550                 :                :     /*
                                551                 :                :      * In the unlikely event that we can't open pg_ident.conf, we throw an
                                552                 :                :      * error, rather than trying to report it via some sort of view entry.
                                553                 :                :      * (Most other error conditions should result in a message in a view
                                554                 :                :      * entry.)
                                555                 :                :      */
 1079                           556                 :              3 :     file = open_auth_file(IdentFileName, ERROR, 0, NULL);
                                557                 :                : 
 1069                           558                 :              3 :     tokenize_auth_file(IdentFileName, file, &ident_lines, DEBUG3, 0);
                                559                 :                : 
                                560                 :                :     /* Now parse all the lines */
 1309                           561                 :              3 :     identcxt = AllocSetContextCreate(CurrentMemoryContext,
                                562                 :                :                                      "ident parser context",
                                563                 :                :                                      ALLOCSET_SMALL_SIZES);
                                564                 :              3 :     oldcxt = MemoryContextSwitchTo(identcxt);
                                565   [ -  +  -  -  :              3 :     foreach(line, ident_lines)
                                              -  + ]
                                566                 :                :     {
 1309 michael@paquier.xyz       567                 :LBC         (8) :         TokenizedAuthLine *tok_line = (TokenizedAuthLine *) lfirst(line);
                                568                 :            (8) :         IdentLine  *identline = NULL;
                                569                 :                : 
                                570                 :                :         /* don't parse lines that already have errors */
                                571         [ #  # ]:            (8) :         if (tok_line->err_msg == NULL)
                                572                 :            (8) :             identline = parse_ident_line(tok_line, DEBUG3);
                                573                 :                : 
                                574                 :                :         /* no error, set a new mapping number */
 1098                           575         [ #  # ]:            (8) :         if (tok_line->err_msg == NULL)
                                576                 :            (8) :             map_number++;
                                577                 :                : 
                                578                 :            (8) :         fill_ident_line(tuple_store, tupdesc, map_number,
                                579                 :                :                         tok_line->file_name, tok_line->line_num,
 1069                           580                 :            (8) :                         identline, tok_line->err_msg);
                                581                 :                :     }
                                582                 :                : 
                                583                 :                :     /* Free tokenizer memory */
 1069 michael@paquier.xyz       584                 :CBC           3 :     free_auth_file(file, 0);
                                585                 :                :     /* Free parse_ident_line memory */
 1309                           586                 :              3 :     MemoryContextSwitchTo(oldcxt);
                                587                 :              3 :     MemoryContextDelete(identcxt);
                                588                 :              3 : }
                                589                 :                : 
                                590                 :                : /*
                                591                 :                :  * SQL-accessible SRF to return all the entries in the pg_ident.conf file.
                                592                 :                :  */
                                593                 :                : Datum
                                594                 :              3 : pg_ident_file_mappings(PG_FUNCTION_ARGS)
                                595                 :                : {
                                596                 :                :     ReturnSetInfo *rsi;
                                597                 :                : 
                                598                 :                :     /*
                                599                 :                :      * Build tuplestore to hold the result rows.  We must use the Materialize
                                600                 :                :      * mode to be safe against HBA file changes while the cursor is open. It's
                                601                 :                :      * also more efficient than having to look up our current position in the
                                602                 :                :      * parsed list every time.
                                603                 :                :      */
 1106                           604                 :              3 :     InitMaterializedSRF(fcinfo, 0);
                                605                 :                : 
                                606                 :                :     /* Fill the tuplestore */
 1309                           607                 :              3 :     rsi = (ReturnSetInfo *) fcinfo->resultinfo;
                                608                 :              3 :     fill_ident_view(rsi->setResult, rsi->setDesc);
                                609                 :                : 
                                610                 :              3 :     PG_RETURN_NULL();
                                611                 :                : }
        

Generated by: LCOV version 2.4-beta