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