LCOV - code coverage report
Current view: top level - src/backend/utils/misc - superuser.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 21 21 100.0 %
Date: 2019-08-24 15:07:19 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-2019, 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 "utils/inval.h"
      26             : #include "utils/syscache.h"
      27             : #include "miscadmin.h"
      28             : 
      29             : 
      30             : /*
      31             :  * In common cases the same roleid (ie, the session or current ID) will
      32             :  * be queried repeatedly.  So we maintain a simple one-entry cache for
      33             :  * the status of the last requested roleid.  The cache can be flushed
      34             :  * at need by watching for cache update events on pg_authid.
      35             :  */
      36             : static Oid  last_roleid = InvalidOid;   /* InvalidOid == cache not valid */
      37             : static bool last_roleid_is_super = false;
      38             : static bool roleid_callback_registered = false;
      39             : 
      40             : static void RoleidCallback(Datum arg, int cacheid, uint32 hashvalue);
      41             : 
      42             : 
      43             : /*
      44             :  * The Postgres user running this command has Postgres superuser privileges
      45             :  */
      46             : bool
      47       52130 : superuser(void)
      48             : {
      49       52130 :     return superuser_arg(GetUserId());
      50             : }
      51             : 
      52             : 
      53             : /*
      54             :  * The specified role has Postgres superuser privileges
      55             :  */
      56             : bool
      57     3714422 : superuser_arg(Oid roleid)
      58             : {
      59             :     bool        result;
      60             :     HeapTuple   rtup;
      61             : 
      62             :     /* Quick out for cache hit */
      63     3714422 :     if (OidIsValid(last_roleid) && last_roleid == roleid)
      64     2510032 :         return last_roleid_is_super;
      65             : 
      66             :     /* Special escape path in case you deleted all your users. */
      67     1204390 :     if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID)
      68     1181120 :         return true;
      69             : 
      70             :     /* OK, look up the information in pg_authid */
      71       23270 :     rtup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
      72       23270 :     if (HeapTupleIsValid(rtup))
      73             :     {
      74       23266 :         result = ((Form_pg_authid) GETSTRUCT(rtup))->rolsuper;
      75       23266 :         ReleaseSysCache(rtup);
      76             :     }
      77             :     else
      78             :     {
      79             :         /* Report "not superuser" for invalid roleids */
      80           4 :         result = false;
      81             :     }
      82             : 
      83             :     /* If first time through, set up callback for cache flushes */
      84       23270 :     if (!roleid_callback_registered)
      85             :     {
      86        8704 :         CacheRegisterSyscacheCallback(AUTHOID,
      87             :                                       RoleidCallback,
      88             :                                       (Datum) 0);
      89        8704 :         roleid_callback_registered = true;
      90             :     }
      91             : 
      92             :     /* Cache the result for next time */
      93       23270 :     last_roleid = roleid;
      94       23270 :     last_roleid_is_super = result;
      95             : 
      96       23270 :     return result;
      97             : }
      98             : 
      99             : /*
     100             :  * RoleidCallback
     101             :  *      Syscache inval callback function
     102             :  */
     103             : static void
     104        9094 : RoleidCallback(Datum arg, int cacheid, uint32 hashvalue)
     105             : {
     106             :     /* Invalidate our local cache in case role's superuserness changed */
     107        9094 :     last_roleid = InvalidOid;
     108        9094 : }

Generated by: LCOV version 1.13