LCOV - differential code coverage report
Current view: top level - src/test/modules/test_oat_hooks - test_oat_hooks.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 76.1 % 155 118 1 4 20 12 7 64 6 41 18 67 6
Current Date: 2023-04-08 15:15:32 Functions: 91.7 % 12 11 1 9 1 1 1 10
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*--------------------------------------------------------------------------
       2                 :  *
       3                 :  * test_oat_hooks.c
       4                 :  *      Code for testing mandatory access control (MAC) using object access hooks.
       5                 :  *
       6                 :  * Copyright (c) 2015-2023, PostgreSQL Global Development Group
       7                 :  *
       8                 :  * IDENTIFICATION
       9                 :  *      src/test/modules/test_oat_hooks/test_oat_hooks.c
      10                 :  *
      11                 :  * -------------------------------------------------------------------------
      12                 :  */
      13                 : 
      14                 : #include "postgres.h"
      15                 : 
      16                 : #include "access/parallel.h"
      17                 : #include "catalog/dependency.h"
      18                 : #include "catalog/objectaccess.h"
      19                 : #include "catalog/pg_proc.h"
      20                 : #include "executor/executor.h"
      21                 : #include "fmgr.h"
      22                 : #include "miscadmin.h"
      23                 : #include "tcop/utility.h"
      24                 : 
      25 CBC           1 : PG_MODULE_MAGIC;
      26                 : 
      27                 : /*
      28                 :  * GUCs controlling which operations to deny
      29                 :  */
      30                 : static bool REGRESS_deny_set_variable = false;
      31                 : static bool REGRESS_deny_alter_system = false;
      32                 : static bool REGRESS_deny_object_access = false;
      33                 : static bool REGRESS_deny_exec_perms = false;
      34                 : static bool REGRESS_deny_utility_commands = false;
      35                 : static bool REGRESS_audit = false;
      36                 : 
      37                 : /*
      38                 :  * GUCs for testing privileges on USERSET and SUSET variables,
      39                 :  * with and without privileges granted prior to module load.
      40                 :  */
      41                 : static bool REGRESS_userset_variable1 = false;
      42                 : static bool REGRESS_userset_variable2 = false;
      43                 : static bool REGRESS_suset_variable1 = false;
      44                 : static bool REGRESS_suset_variable2 = false;
      45                 : 
      46                 : /* Saved hook values */
      47                 : static object_access_hook_type next_object_access_hook = NULL;
      48                 : static object_access_hook_type_str next_object_access_hook_str = NULL;
      49                 : static ExecutorCheckPerms_hook_type next_exec_check_perms_hook = NULL;
      50                 : static ProcessUtility_hook_type next_ProcessUtility_hook = NULL;
      51                 : 
      52                 : /* Test Object Access Type Hook hooks */
      53                 : static void REGRESS_object_access_hook_str(ObjectAccessType access,
      54                 :                                            Oid classId, const char *objName,
      55                 :                                            int subId, void *arg);
      56                 : static void REGRESS_object_access_hook(ObjectAccessType access, Oid classId,
      57                 :                                        Oid objectId, int subId, void *arg);
      58                 : static bool REGRESS_exec_check_perms(List *rangeTabls, List *rteperminfos, bool do_abort);
      59                 : static void REGRESS_utility_command(PlannedStmt *pstmt,
      60                 :                                     const char *queryString, bool readOnlyTree,
      61                 :                                     ProcessUtilityContext context,
      62                 :                                     ParamListInfo params,
      63                 :                                     QueryEnvironment *queryEnv,
      64                 :                                     DestReceiver *dest, QueryCompletion *qc);
      65                 : 
      66                 : /* Helper functions */
      67                 : static char *accesstype_to_string(ObjectAccessType access, int subId);
      68                 : static char *accesstype_arg_to_string(ObjectAccessType access, void *arg);
      69                 : 
      70                 : 
      71                 : /*
      72                 :  * Module load callback
      73 ECB             :  */
      74                 : void
      75 GIC           1 : _PG_init(void)
      76                 : {
      77                 :     /*
      78 ECB             :      * test_oat_hooks.deny_set_variable = (on|off)
      79                 :      */
      80 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.deny_set_variable",
      81                 :                              "Deny non-superuser set permissions",
      82                 :                              NULL,
      83                 :                              &REGRESS_deny_set_variable,
      84                 :                              false,
      85                 :                              PGC_SUSET,
      86                 :                              GUC_NOT_IN_SAMPLE,
      87                 :                              NULL,
      88                 :                              NULL,
      89                 :                              NULL);
      90                 : 
      91                 :     /*
      92 ECB             :      * test_oat_hooks.deny_alter_system = (on|off)
      93                 :      */
      94 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.deny_alter_system",
      95                 :                              "Deny non-superuser alter system set permissions",
      96                 :                              NULL,
      97                 :                              &REGRESS_deny_alter_system,
      98                 :                              false,
      99                 :                              PGC_SUSET,
     100                 :                              GUC_NOT_IN_SAMPLE,
     101                 :                              NULL,
     102                 :                              NULL,
     103                 :                              NULL);
     104                 : 
     105                 :     /*
     106 ECB             :      * test_oat_hooks.deny_object_access = (on|off)
     107                 :      */
     108 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.deny_object_access",
     109                 :                              "Deny non-superuser object access permissions",
     110                 :                              NULL,
     111                 :                              &REGRESS_deny_object_access,
     112                 :                              false,
     113                 :                              PGC_SUSET,
     114                 :                              GUC_NOT_IN_SAMPLE,
     115                 :                              NULL,
     116                 :                              NULL,
     117                 :                              NULL);
     118                 : 
     119                 :     /*
     120 ECB             :      * test_oat_hooks.deny_exec_perms = (on|off)
     121                 :      */
     122 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.deny_exec_perms",
     123                 :                              "Deny non-superuser exec permissions",
     124                 :                              NULL,
     125                 :                              &REGRESS_deny_exec_perms,
     126                 :                              false,
     127                 :                              PGC_SUSET,
     128                 :                              GUC_NOT_IN_SAMPLE,
     129                 :                              NULL,
     130                 :                              NULL,
     131                 :                              NULL);
     132                 : 
     133                 :     /*
     134 ECB             :      * test_oat_hooks.deny_utility_commands = (on|off)
     135                 :      */
     136 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.deny_utility_commands",
     137                 :                              "Deny non-superuser utility commands",
     138                 :                              NULL,
     139                 :                              &REGRESS_deny_utility_commands,
     140                 :                              false,
     141                 :                              PGC_SUSET,
     142                 :                              GUC_NOT_IN_SAMPLE,
     143                 :                              NULL,
     144                 :                              NULL,
     145                 :                              NULL);
     146                 : 
     147                 :     /*
     148 ECB             :      * test_oat_hooks.audit = (on|off)
     149                 :      */
     150 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.audit",
     151                 :                              "Turn on/off debug audit messages",
     152                 :                              NULL,
     153                 :                              &REGRESS_audit,
     154                 :                              false,
     155                 :                              PGC_SUSET,
     156                 :                              GUC_NOT_IN_SAMPLE,
     157                 :                              NULL,
     158                 :                              NULL,
     159                 :                              NULL);
     160                 : 
     161                 :     /*
     162 ECB             :      * test_oat_hooks.user_var{1,2} = (on|off)
     163                 :      */
     164 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.user_var1",
     165                 :                              "Dummy parameter settable by public",
     166                 :                              NULL,
     167                 :                              &REGRESS_userset_variable1,
     168                 :                              false,
     169                 :                              PGC_USERSET,
     170                 :                              GUC_NOT_IN_SAMPLE,
     171                 :                              NULL,
     172                 :                              NULL,
     173 ECB             :                              NULL);
     174                 : 
     175 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.user_var2",
     176                 :                              "Dummy parameter settable by public",
     177                 :                              NULL,
     178                 :                              &REGRESS_userset_variable2,
     179                 :                              false,
     180                 :                              PGC_USERSET,
     181                 :                              GUC_NOT_IN_SAMPLE,
     182                 :                              NULL,
     183                 :                              NULL,
     184                 :                              NULL);
     185                 : 
     186                 :     /*
     187 ECB             :      * test_oat_hooks.super_var{1,2} = (on|off)
     188                 :      */
     189 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.super_var1",
     190                 :                              "Dummy parameter settable by superuser",
     191                 :                              NULL,
     192                 :                              &REGRESS_suset_variable1,
     193                 :                              false,
     194                 :                              PGC_SUSET,
     195                 :                              GUC_NOT_IN_SAMPLE,
     196                 :                              NULL,
     197                 :                              NULL,
     198 ECB             :                              NULL);
     199                 : 
     200 GIC           1 :     DefineCustomBoolVariable("test_oat_hooks.super_var2",
     201                 :                              "Dummy parameter settable by superuser",
     202                 :                              NULL,
     203                 :                              &REGRESS_suset_variable2,
     204                 :                              false,
     205                 :                              PGC_SUSET,
     206                 :                              GUC_NOT_IN_SAMPLE,
     207                 :                              NULL,
     208                 :                              NULL,
     209 ECB             :                              NULL);
     210                 : 
     211 GIC           1 :     MarkGUCPrefixReserved("test_oat_hooks");
     212 ECB             : 
     213                 :     /* Object access hook */
     214 GIC           1 :     next_object_access_hook = object_access_hook;
     215               1 :     object_access_hook = REGRESS_object_access_hook;
     216 ECB             : 
     217                 :     /* Object access hook str */
     218 GIC           1 :     next_object_access_hook_str = object_access_hook_str;
     219               1 :     object_access_hook_str = REGRESS_object_access_hook_str;
     220 ECB             : 
     221                 :     /* DML permission check */
     222 GIC           1 :     next_exec_check_perms_hook = ExecutorCheckPerms_hook;
     223               1 :     ExecutorCheckPerms_hook = REGRESS_exec_check_perms;
     224 ECB             : 
     225                 :     /* ProcessUtility hook */
     226 CBC           1 :     next_ProcessUtility_hook = ProcessUtility_hook;
     227 GIC           1 :     ProcessUtility_hook = REGRESS_utility_command;
     228               1 : }
     229 ECB             : 
     230                 : static void
     231 GIC         182 : emit_audit_message(const char *type, const char *hook, char *action, char *objName)
     232                 : {
     233                 :     /*
     234                 :      * Ensure that audit messages are not duplicated by only emitting them
     235                 :      * from a leader process, not a worker process. This makes the test
     236                 :      * results deterministic even if run with debug_parallel_query = regress.
     237                 :      */
     238 CBC         182 :     if (REGRESS_audit && !IsParallelWorker())
     239                 :     {
     240             165 :         const char *who = superuser_arg(GetUserId()) ? "superuser" : "non-superuser";
     241 ECB             : 
     242 GIC         165 :         if (objName)
     243              69 :             ereport(NOTICE,
     244                 :                     (errcode(ERRCODE_INTERNAL_ERROR),
     245 ECB             :                      errmsg("in %s: %s %s %s [%s]", hook, who, type, action, objName)));
     246                 :         else
     247 GIC          96 :             ereport(NOTICE,
     248                 :                     (errcode(ERRCODE_INTERNAL_ERROR),
     249                 :                      errmsg("in %s: %s %s %s", hook, who, type, action)));
     250 ECB             :     }
     251                 : 
     252 CBC         182 :     if (action)
     253             182 :         pfree(action);
     254             182 :     if (objName)
     255 GIC          77 :         pfree(objName);
     256             182 : }
     257 ECB             : 
     258                 : static void
     259 CBC          97 : audit_attempt(const char *hook, char *action, char *objName)
     260 ECB             : {
     261 GIC          97 :     emit_audit_message("attempting", hook, action, objName);
     262              97 : }
     263 ECB             : 
     264                 : static void
     265 CBC          85 : audit_success(const char *hook, char *action, char *objName)
     266 ECB             : {
     267 GIC          85 :     emit_audit_message("finished", hook, action, objName);
     268              85 : }
     269 EUB             : 
     270                 : static void
     271 UBC           0 : audit_failure(const char *hook, char *action, char *objName)
     272 EUB             : {
     273 UIC           0 :     emit_audit_message("denied", hook, action, objName);
     274               0 : }
     275 ECB             : 
     276                 : static void
     277 CBC          23 : REGRESS_object_access_hook_str(ObjectAccessType access, Oid classId, const char *objName, int subId, void *arg)
     278                 : {
     279 GIC          23 :     audit_attempt("object_access_hook_str",
     280                 :                   accesstype_to_string(access, subId),
     281 ECB             :                   pstrdup(objName));
     282                 : 
     283 GBC          23 :     if (next_object_access_hook_str)
     284                 :     {
     285 UIC           0 :         (*next_object_access_hook_str) (access, classId, objName, subId, arg);
     286 ECB             :     }
     287                 : 
     288 CBC          23 :     switch (access)
     289 ECB             :     {
     290 GIC          23 :         case OAT_POST_ALTER:
     291 GBC          23 :             if ((subId & ACL_SET) && (subId & ACL_ALTER_SYSTEM))
     292 EUB             :             {
     293 UIC           0 :                 if (REGRESS_deny_set_variable && !superuser_arg(GetUserId()))
     294               0 :                     ereport(ERROR,
     295                 :                             (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     296 ECB             :                              errmsg("permission denied: all privileges %s", objName)));
     297                 :             }
     298 CBC          23 :             else if (subId & ACL_SET)
     299 ECB             :             {
     300 GIC          19 :                 if (REGRESS_deny_set_variable && !superuser_arg(GetUserId()))
     301               1 :                     ereport(ERROR,
     302                 :                             (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     303 ECB             :                              errmsg("permission denied: set %s", objName)));
     304                 :             }
     305 CBC           4 :             else if (subId & ACL_ALTER_SYSTEM)
     306 EUB             :             {
     307 GIC           4 :                 if (REGRESS_deny_alter_system && !superuser_arg(GetUserId()))
     308 UIC           0 :                     ereport(ERROR,
     309                 :                             (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     310                 :                              errmsg("permission denied: alter system set %s", objName)));
     311 EUB             :             }
     312 ECB             :             else
     313 UBC           0 :                 elog(ERROR, "Unknown ParameterAclRelationId subId: %d", subId);
     314 GBC          22 :             break;
     315 UIC           0 :         default:
     316               0 :             break;
     317 ECB             :     }
     318                 : 
     319 GIC          22 :     audit_success("object_access_hook_str",
     320 ECB             :                   accesstype_to_string(access, subId),
     321                 :                   pstrdup(objName));
     322 GIC          22 : }
     323 ECB             : 
     324                 : static void
     325 CBC          16 : REGRESS_object_access_hook(ObjectAccessType access, Oid classId, Oid objectId, int subId, void *arg)
     326                 : {
     327 GIC          16 :     audit_attempt("object access",
     328                 :                   accesstype_to_string(access, 0),
     329 ECB             :                   accesstype_arg_to_string(access, arg));
     330 EUB             : 
     331 GIC          16 :     if (REGRESS_deny_object_access && !superuser_arg(GetUserId()))
     332 UIC           0 :         ereport(ERROR,
     333                 :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     334                 :                  errmsg("permission denied: %s [%s]",
     335                 :                         accesstype_to_string(access, 0),
     336                 :                         accesstype_arg_to_string(access, arg))));
     337 ECB             : 
     338 EUB             :     /* Forward to next hook in the chain */
     339 GIC          16 :     if (next_object_access_hook)
     340 LBC           0 :         (*next_object_access_hook) (access, classId, objectId, subId, arg);
     341                 : 
     342 GIC          16 :     audit_success("object access",
     343 ECB             :                   accesstype_to_string(access, 0),
     344                 :                   accesstype_arg_to_string(access, arg));
     345 GIC          16 : }
     346 ECB             : 
     347                 : static bool
     348 GNC           6 : REGRESS_exec_check_perms(List *rangeTabls, List *rteperminfos, bool do_abort)
     349 ECB             : {
     350 GIC           6 :     bool        am_super = superuser_arg(GetUserId());
     351 CBC           6 :     bool        allow = true;
     352                 : 
     353 GIC           6 :     audit_attempt("executor check perms", pstrdup("execute"), NULL);
     354 ECB             : 
     355                 :     /* Perform our check */
     356 GBC           6 :     allow = !REGRESS_deny_exec_perms || am_super;
     357 GIC           6 :     if (do_abort && !allow)
     358 UIC           0 :         ereport(ERROR,
     359                 :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     360                 :                  errmsg("permission denied: %s", "execute")));
     361 ECB             : 
     362 EUB             :     /* Forward to next hook in the chain */
     363 GBC           6 :     if (next_exec_check_perms_hook &&
     364 UNC           0 :         !(*next_exec_check_perms_hook) (rangeTabls, rteperminfos, do_abort))
     365 LBC           0 :         allow = false;
     366 ECB             : 
     367 GIC           6 :     if (allow)
     368               6 :         audit_success("executor check perms",
     369                 :                       pstrdup("execute"),
     370 EUB             :                       NULL);
     371                 :     else
     372 UIC           0 :         audit_failure("executor check perms",
     373                 :                       pstrdup("execute"),
     374 ECB             :                       NULL);
     375                 : 
     376 GIC           6 :     return allow;
     377                 : }
     378 ECB             : 
     379                 : static void
     380 GIC          52 : REGRESS_utility_command(PlannedStmt *pstmt,
     381                 :                         const char *queryString,
     382                 :                         bool readOnlyTree,
     383                 :                         ProcessUtilityContext context,
     384                 :                         ParamListInfo params,
     385                 :                         QueryEnvironment *queryEnv,
     386                 :                         DestReceiver *dest,
     387 ECB             :                         QueryCompletion *qc)
     388                 : {
     389 GIC          52 :     Node       *parsetree = pstmt->utilityStmt;
     390 CBC          52 :     const char *action = GetCommandTagName(CreateCommandTag(parsetree));
     391                 : 
     392 GIC          52 :     audit_attempt("process utility",
     393                 :                   pstrdup(action),
     394                 :                   NULL);
     395 ECB             : 
     396 EUB             :     /* Check permissions */
     397 GIC          52 :     if (REGRESS_deny_utility_commands && !superuser_arg(GetUserId()))
     398 UIC           0 :         ereport(ERROR,
     399                 :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
     400                 :                  errmsg("permission denied: %s", action)));
     401 ECB             : 
     402 EUB             :     /* Forward to next hook in the chain */
     403 GIC          52 :     if (next_ProcessUtility_hook)
     404 UIC           0 :         (*next_ProcessUtility_hook) (pstmt, queryString, readOnlyTree,
     405                 :                                      context, params, queryEnv,
     406 ECB             :                                      dest, qc);
     407                 :     else
     408 GIC          52 :         standard_ProcessUtility(pstmt, queryString, readOnlyTree,
     409                 :                                 context, params, queryEnv,
     410                 :                                 dest, qc);
     411 ECB             : 
     412                 :     /* We're done */
     413 GIC          41 :     audit_success("process utility",
     414 ECB             :                   pstrdup(action),
     415                 :                   NULL);
     416 GIC          41 : }
     417 ECB             : 
     418                 : static char *
     419 GIC          77 : accesstype_to_string(ObjectAccessType access, int subId)
     420                 : {
     421 ECB             :     const char *type;
     422                 : 
     423 CBC          77 :     switch (access)
     424 ECB             :     {
     425 CBC          16 :         case OAT_POST_CREATE:
     426              16 :             type = "create";
     427              16 :             break;
     428              10 :         case OAT_DROP:
     429              10 :             type = "drop";
     430              10 :             break;
     431              45 :         case OAT_POST_ALTER:
     432              45 :             type = "alter";
     433              45 :             break;
     434               6 :         case OAT_NAMESPACE_SEARCH:
     435 GBC           6 :             type = "namespace search";
     436               6 :             break;
     437 UBC           0 :         case OAT_FUNCTION_EXECUTE:
     438               0 :             type = "execute";
     439               0 :             break;
     440               0 :         case OAT_TRUNCATE:
     441               0 :             type = "truncate";
     442               0 :             break;
     443 UIC           0 :         default:
     444               0 :             type = "UNRECOGNIZED ObjectAccessType";
     445 ECB             :     }
     446 EUB             : 
     447 CBC          77 :     if ((subId & ACL_SET) && (subId & ACL_ALTER_SYSTEM))
     448 LBC           0 :         return psprintf("%s (subId=0x%x, all privileges)", type, subId);
     449 CBC          77 :     if (subId & ACL_SET)
     450              37 :         return psprintf("%s (subId=0x%x, set)", type, subId);
     451 GIC          40 :     if (subId & ACL_ALTER_SYSTEM)
     452 CBC           8 :         return psprintf("%s (subId=0x%x, alter system)", type, subId);
     453                 : 
     454 GIC          32 :     return psprintf("%s (subId=0x%x)", type, subId);
     455                 : }
     456 ECB             : 
     457                 : static char *
     458 CBC          32 : accesstype_arg_to_string(ObjectAccessType access, void *arg)
     459 EUB             : {
     460 GIC          32 :     if (arg == NULL)
     461 LBC           0 :         return pstrdup("extra info null");
     462                 : 
     463 CBC          32 :     switch (access)
     464                 :     {
     465              16 :         case OAT_POST_CREATE:
     466                 :             {
     467              16 :                 ObjectAccessPostCreate *pc_arg = (ObjectAccessPostCreate *) arg;
     468                 : 
     469 GIC          16 :                 return pstrdup(pc_arg->is_internal ? "internal" : "explicit");
     470 ECB             :             }
     471                 :             break;
     472 CBC          10 :         case OAT_DROP:
     473                 :             {
     474              10 :                 ObjectAccessDrop *drop_arg = (ObjectAccessDrop *) arg;
     475 ECB             : 
     476 GIC          60 :                 return psprintf("%s%s%s%s%s%s",
     477 CBC          10 :                                 ((drop_arg->dropflags & PERFORM_DELETION_INTERNAL)
     478                 :                                  ? "internal action," : ""),
     479 GNC          10 :                                 ((drop_arg->dropflags & PERFORM_DELETION_CONCURRENTLY)
     480                 :                                  ? "concurrent drop," : ""),
     481              10 :                                 ((drop_arg->dropflags & PERFORM_DELETION_QUIETLY)
     482                 :                                  ? "suppress notices," : ""),
     483              10 :                                 ((drop_arg->dropflags & PERFORM_DELETION_SKIP_ORIGINAL)
     484                 :                                  ? "keep original object," : ""),
     485              10 :                                 ((drop_arg->dropflags & PERFORM_DELETION_SKIP_EXTENSIONS)
     486                 :                                  ? "keep extensions," : ""),
     487              10 :                                 ((drop_arg->dropflags & PERFORM_DELETION_CONCURRENT_LOCK)
     488                 :                                  ? "normal concurrent drop," : ""));
     489 EUB             :             }
     490                 :             break;
     491 UBC           0 :         case OAT_POST_ALTER:
     492                 :             {
     493               0 :                 ObjectAccessPostAlter *pa_arg = (ObjectAccessPostAlter *) arg;
     494 EUB             : 
     495 UBC           0 :                 return psprintf("%s %s auxiliary object",
     496 UIC           0 :                                 (pa_arg->is_internal ? "internal" : "explicit"),
     497               0 :                                 (OidIsValid(pa_arg->auxiliary_id) ? "with" : "without"));
     498 ECB             :             }
     499                 :             break;
     500 CBC           6 :         case OAT_NAMESPACE_SEARCH:
     501                 :             {
     502               6 :                 ObjectAccessNamespaceSearch *ns_arg = (ObjectAccessNamespaceSearch *) arg;
     503 ECB             : 
     504 CBC          12 :                 return psprintf("%s, %s",
     505 GIC           6 :                                 (ns_arg->ereport_on_violation ? "report on violation" : "no report on violation"),
     506               6 :                                 (ns_arg->result ? "allowed" : "denied"));
     507 EUB             :             }
     508                 :             break;
     509 UIC           0 :         case OAT_TRUNCATE:
     510 EUB             :         case OAT_FUNCTION_EXECUTE:
     511                 :             /* hook takes no arg. */
     512 UBC           0 :             return pstrdup("unexpected extra info pointer received");
     513 UIC           0 :         default:
     514               0 :             return pstrdup("cannot parse extra info for unrecognized access type");
     515                 :     }
     516                 : 
     517                 :     return pstrdup("unknown");
     518                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a