PostgreSQL Source Code  git master
superuser.c
Go to the documentation of this file.
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 superuser(void)
47 {
48  return superuser_arg(GetUserId());
49 }
50 
51 
52 /*
53  * The specified role has Postgres superuser privileges
54  */
55 bool
57 {
58  bool result;
59  HeapTuple rtup;
60 
61  /* Quick out for cache hit */
62  if (OidIsValid(last_roleid) && last_roleid == roleid)
63  return last_roleid_is_super;
64 
65  /* Special escape path in case you deleted all your users. */
66  if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID)
67  return true;
68 
69  /* OK, look up the information in pg_authid */
70  rtup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
71  if (HeapTupleIsValid(rtup))
72  {
73  result = ((Form_pg_authid) GETSTRUCT(rtup))->rolsuper;
74  ReleaseSysCache(rtup);
75  }
76  else
77  {
78  /* Report "not superuser" for invalid roleids */
79  result = false;
80  }
81 
82  /* If first time through, set up callback for cache flushes */
84  {
87  (Datum) 0);
89  }
90 
91  /* Cache the result for next time */
92  last_roleid = roleid;
93  last_roleid_is_super = result;
94 
95  return result;
96 }
97 
98 /*
99  * RoleidCallback
100  * Syscache inval callback function
101  */
102 static void
103 RoleidCallback(Datum arg, int cacheid, uint32 hashvalue)
104 {
105  /* Invalidate our local cache in case role's superuserness changed */
107 }
unsigned int uint32
Definition: c.h:493
#define OidIsValid(objectId)
Definition: c.h:762
bool IsUnderPostmaster
Definition: globals.c:117
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1516
Oid GetUserId(void)
Definition: miscinit.c:514
bool rolsuper
Definition: pg_authid.h:35
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void * arg
uintptr_t Datum
Definition: postgres.h:64
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
static Oid last_roleid
Definition: superuser.c:35
static bool roleid_callback_registered
Definition: superuser.c:37
static void RoleidCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: superuser.c:103
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
static bool last_roleid_is_super
Definition: superuser.c:36
bool superuser(void)
Definition: superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218