LCOV - code coverage report
Current view: top level - src/backend/utils/misc - superuser.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 21 21 100.0 %
Date: 2024-04-25 23:11:32 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * superuser.c
       4             :  *    The superuser() function.  Determines if user has superuser privilege.
       5             :  *
       6             :  * All code should use either of these two functions to find out
       7             :  * whether a given user is a superuser, rather than examining
       8             :  * pg_authid.rolsuper directly, so that the escape hatch built in for
       9             :  * the single-user case works.
      10             :  *
      11             :  *
      12             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
      13             :  * Portions Copyright (c) 1994, Regents of the University of California
      14             :  *
      15             :  *
      16             :  * IDENTIFICATION
      17             :  *    src/backend/utils/misc/superuser.c
      18             :  *
      19             :  *-------------------------------------------------------------------------
      20             :  */
      21             : #include "postgres.h"
      22             : 
      23             : #include "access/htup_details.h"
      24             : #include "catalog/pg_authid.h"
      25             : #include "miscadmin.h"
      26             : #include "utils/inval.h"
      27             : #include "utils/syscache.h"
      28             : 
      29             : /*
      30             :  * In common cases the same roleid (ie, the session or current ID) will
      31             :  * be queried repeatedly.  So we maintain a simple one-entry cache for
      32             :  * the status of the last requested roleid.  The cache can be flushed
      33             :  * at need by watching for cache update events on pg_authid.
      34             :  */
      35             : static Oid  last_roleid = InvalidOid;   /* InvalidOid == cache not valid */
      36             : static bool last_roleid_is_super = false;
      37             : static bool roleid_callback_registered = false;
      38             : 
      39             : static void RoleidCallback(Datum arg, int cacheid, uint32 hashvalue);
      40             : 
      41             : 
      42             : /*
      43             :  * The Postgres user running this command has Postgres superuser privileges
      44             :  */
      45             : bool
      46       93696 : superuser(void)
      47             : {
      48       93696 :     return superuser_arg(GetUserId());
      49             : }
      50             : 
      51             : 
      52             : /*
      53             :  * The specified role has Postgres superuser privileges
      54             :  */
      55             : bool
      56     6123324 : superuser_arg(Oid roleid)
      57             : {
      58             :     bool        result;
      59             :     HeapTuple   rtup;
      60             : 
      61             :     /* Quick out for cache hit */
      62     6123324 :     if (OidIsValid(last_roleid) && last_roleid == roleid)
      63     5763864 :         return last_roleid_is_super;
      64             : 
      65             :     /* Special escape path in case you deleted all your users. */
      66      359460 :     if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID)
      67      308112 :         return true;
      68             : 
      69             :     /* OK, look up the information in pg_authid */
      70       51348 :     rtup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
      71       51348 :     if (HeapTupleIsValid(rtup))
      72             :     {
      73       51342 :         result = ((Form_pg_authid) GETSTRUCT(rtup))->rolsuper;
      74       51342 :         ReleaseSysCache(rtup);
      75             :     }
      76             :     else
      77             :     {
      78             :         /* Report "not superuser" for invalid roleids */
      79           6 :         result = false;
      80             :     }
      81             : 
      82             :     /* If first time through, set up callback for cache flushes */
      83       51348 :     if (!roleid_callback_registered)
      84             :     {
      85       24310 :         CacheRegisterSyscacheCallback(AUTHOID,
      86             :                                       RoleidCallback,
      87             :                                       (Datum) 0);
      88       24310 :         roleid_callback_registered = true;
      89             :     }
      90             : 
      91             :     /* Cache the result for next time */
      92       51348 :     last_roleid = roleid;
      93       51348 :     last_roleid_is_super = result;
      94             : 
      95       51348 :     return result;
      96             : }
      97             : 
      98             : /*
      99             :  * RoleidCallback
     100             :  *      Syscache inval callback function
     101             :  */
     102             : static void
     103       19868 : RoleidCallback(Datum arg, int cacheid, uint32 hashvalue)
     104             : {
     105             :     /* Invalidate our local cache in case role's superuserness changed */
     106       19868 :     last_roleid = InvalidOid;
     107       19868 : }

Generated by: LCOV version 1.14