LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - hbafuncs.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 49.3 % 229 113 116 113
Current Date: 2024-04-14 14:21:10 Functions: 85.7 % 7 6 1 6
Baseline: 16@8cea358b128 Branches: 36.8 % 136 50 86 50
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 49.3 % 229 113 116 113
Function coverage date bins:
(240..) days: 85.7 % 7 6 1 6
Branch coverage date bins:
(240..) days: 36.8 % 136 50 86 50

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

Generated by: LCOV version 2.1-beta2-3-g6141622