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

Generated by: LCOV version 2.4-beta