PostgreSQL Source Code  git master
objectaccess.h
Go to the documentation of this file.
1 /*
2  * objectaccess.h
3  *
4  * Object access hooks.
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  */
9 
10 #ifndef OBJECTACCESS_H
11 #define OBJECTACCESS_H
12 
13 /*
14  * Object access hooks are intended to be called just before or just after
15  * performing certain actions on a SQL object. This is intended as
16  * infrastructure for security or logging plugins.
17  *
18  * OAT_POST_CREATE should be invoked just after the object is created.
19  * Typically, this is done after inserting the primary catalog records and
20  * associated dependencies. The command counter may or may not be incremented
21  * at the time the hook is invoked; if not, the extension can use SnapshotSelf
22  * to get the new version of the tuple.
23  *
24  * OAT_DROP should be invoked just before deletion of objects; typically
25  * deleteOneObject(). Its arguments are packed within ObjectAccessDrop.
26  *
27  * OAT_POST_ALTER should be invoked just after the object is altered,
28  * but before the command counter is incremented. An extension using the
29  * hook can use a current MVCC snapshot to get the old version of the tuple,
30  * and can use SnapshotSelf to get the new version of the tuple.
31  *
32  * OAT_NAMESPACE_SEARCH should be invoked prior to object name lookup under
33  * a particular namespace. This event is equivalent to usage permission
34  * on a schema under the default access control mechanism.
35  *
36  * OAT_FUNCTION_EXECUTE should be invoked prior to function execution.
37  * This event is almost equivalent to execute permission on functions,
38  * except for the case when execute permission is checked during object
39  * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are
40  * sufficient for extensions to track these kind of checks.
41  *
42  * OAT_TRUNCATE should be invoked just before truncation of objects. This
43  * event is equivalent to truncate permission on a relation under the
44  * default access control mechanism.
45  *
46  * Other types may be added in the future.
47  */
48 typedef enum ObjectAccessType
49 {
57 
58 /*
59  * Arguments of OAT_POST_CREATE event
60  */
61 typedef struct
62 {
63  /*
64  * This flag informs extensions whether the context of this creation is
65  * invoked by user's operations, or not. E.g, it shall be dealt as
66  * internal stuff on toast tables or indexes due to type changes.
67  */
70 
71 /*
72  * Arguments of OAT_DROP event
73  */
74 typedef struct
75 {
76  /*
77  * Flags to inform extensions the context of this deletion. Also see
78  * PERFORM_DELETION_* in dependency.h
79  */
80  int dropflags;
82 
83 /*
84  * Arguments of OAT_POST_ALTER event
85  */
86 typedef struct
87 {
88  /*
89  * This identifier is used when system catalog takes two IDs to identify a
90  * particular tuple of the catalog. It is only used when the caller want
91  * to identify an entry of pg_inherits, pg_db_role_setting or
92  * pg_user_mapping. Elsewhere, InvalidOid should be set.
93  */
95 
96  /*
97  * If this flag is set, the user hasn't requested that the object be
98  * altered, but we're doing it anyway for some internal reason.
99  * Permissions-checking hooks may want to skip checks if, say, we're alter
100  * the constraints of a temporary heap during CLUSTER.
101  */
104 
105 /*
106  * Arguments of OAT_NAMESPACE_SEARCH
107  */
108 typedef struct
109 {
110  /*
111  * If true, hook should report an error when permission to search this
112  * schema is denied.
113  */
115 
116  /*
117  * This is, in essence, an out parameter. Core code should initialize
118  * this to true, and any extension that wants to deny access should reset
119  * it to false. But an extension should be careful never to store a true
120  * value here, so that in case there are multiple extensions access is
121  * only allowed if all extensions agree.
122  */
123  bool result;
125 
126 /* Plugin provides a hook function matching one or both of these signatures. */
128  Oid classId,
129  Oid objectId,
130  int subId,
131  void *arg);
132 
134  Oid classId,
135  const char *objectStr,
136  int subId,
137  void *arg);
138 
139 /* Plugin sets this variable to a suitable hook function. */
142 
143 
144 /* Core code uses these functions to call the hook (see macros below). */
145 extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
146  bool is_internal);
147 extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,
148  int dropflags);
149 extern void RunObjectTruncateHook(Oid objectId);
150 extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
151  Oid auxiliaryId, bool is_internal);
152 extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation);
153 extern void RunFunctionExecuteHook(Oid objectId);
154 
155 /* String versions */
156 extern void RunObjectPostCreateHookStr(Oid classId, const char *objectName, int subId,
157  bool is_internal);
158 extern void RunObjectDropHookStr(Oid classId, const char *objectName, int subId,
159  int dropflags);
160 extern void RunObjectTruncateHookStr(const char *objectName);
161 extern void RunObjectPostAlterHookStr(Oid classId, const char *objectName, int subId,
162  Oid auxiliaryId, bool is_internal);
163 extern bool RunNamespaceSearchHookStr(const char *objectName, bool ereport_on_violation);
164 extern void RunFunctionExecuteHookStr(const char *objectName);
165 
166 
167 /*
168  * The following macros are wrappers around the functions above; these should
169  * normally be used to invoke the hook in lieu of calling the above functions
170  * directly.
171  */
172 
173 #define InvokeObjectPostCreateHook(classId,objectId,subId) \
174  InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false)
175 #define InvokeObjectPostCreateHookArg(classId,objectId,subId,is_internal) \
176  do { \
177  if (object_access_hook) \
178  RunObjectPostCreateHook((classId),(objectId),(subId), \
179  (is_internal)); \
180  } while(0)
181 
182 #define InvokeObjectDropHook(classId,objectId,subId) \
183  InvokeObjectDropHookArg((classId),(objectId),(subId),0)
184 #define InvokeObjectDropHookArg(classId,objectId,subId,dropflags) \
185  do { \
186  if (object_access_hook) \
187  RunObjectDropHook((classId),(objectId),(subId), \
188  (dropflags)); \
189  } while(0)
190 
191 #define InvokeObjectTruncateHook(objectId) \
192  do { \
193  if (object_access_hook) \
194  RunObjectTruncateHook(objectId); \
195  } while(0)
196 
197 #define InvokeObjectPostAlterHook(classId,objectId,subId) \
198  InvokeObjectPostAlterHookArg((classId),(objectId),(subId), \
199  InvalidOid,false)
200 #define InvokeObjectPostAlterHookArg(classId,objectId,subId, \
201  auxiliaryId,is_internal) \
202  do { \
203  if (object_access_hook) \
204  RunObjectPostAlterHook((classId),(objectId),(subId), \
205  (auxiliaryId),(is_internal)); \
206  } while(0)
207 
208 #define InvokeNamespaceSearchHook(objectId, ereport_on_violation) \
209  (!object_access_hook \
210  ? true \
211  : RunNamespaceSearchHook((objectId), (ereport_on_violation)))
212 
213 #define InvokeFunctionExecuteHook(objectId) \
214  do { \
215  if (object_access_hook) \
216  RunFunctionExecuteHook(objectId); \
217  } while(0)
218 
219 
220 #define InvokeObjectPostCreateHookStr(classId,objectName,subId) \
221  InvokeObjectPostCreateHookArgStr((classId),(objectName),(subId),false)
222 #define InvokeObjectPostCreateHookArgStr(classId,objectName,subId,is_internal) \
223  do { \
224  if (object_access_hook_str) \
225  RunObjectPostCreateHookStr((classId),(objectName),(subId), \
226  (is_internal)); \
227  } while(0)
228 
229 #define InvokeObjectDropHookStr(classId,objectName,subId) \
230  InvokeObjectDropHookArgStr((classId),(objectName),(subId),0)
231 #define InvokeObjectDropHookArgStr(classId,objectName,subId,dropflags) \
232  do { \
233  if (object_access_hook_str) \
234  RunObjectDropHookStr((classId),(objectName),(subId), \
235  (dropflags)); \
236  } while(0)
237 
238 #define InvokeObjectTruncateHookStr(objectName) \
239  do { \
240  if (object_access_hook_str) \
241  RunObjectTruncateHookStr(objectName); \
242  } while(0)
243 
244 #define InvokeObjectPostAlterHookStr(classId,objectName,subId) \
245  InvokeObjectPostAlterHookArgStr((classId),(objectName),(subId), \
246  InvalidOid,false)
247 #define InvokeObjectPostAlterHookArgStr(classId,objectName,subId, \
248  auxiliaryId,is_internal) \
249  do { \
250  if (object_access_hook_str) \
251  RunObjectPostAlterHookStr((classId),(objectName),(subId), \
252  (auxiliaryId),(is_internal)); \
253  } while(0)
254 
255 #define InvokeNamespaceSearchHookStr(objectName, ereport_on_violation) \
256  (!object_access_hook_str \
257  ? true \
258  : RunNamespaceSearchHookStr((objectName), (ereport_on_violation)))
259 
260 #define InvokeFunctionExecuteHookStr(objectName) \
261  do { \
262  if (object_access_hook_str) \
263  RunFunctionExecuteHookStr(objectName); \
264  } while(0)
265 
266 
267 #endif /* OBJECTACCESS_H */
#define PGDLLIMPORT
Definition: c.h:1316
void RunObjectTruncateHookStr(const char *objectName)
Definition: objectaccess.c:202
void RunFunctionExecuteHookStr(const char *objectName)
Definition: objectaccess.c:265
void RunObjectDropHook(Oid classId, Oid objectId, int subId, int dropflags)
Definition: objectaccess.c:54
void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId, Oid auxiliaryId, bool is_internal)
Definition: objectaccess.c:92
void RunFunctionExecuteHook(Oid objectId)
Definition: objectaccess.c:139
bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
Definition: objectaccess.c:115
void(* object_access_hook_type)(ObjectAccessType access, Oid classId, Oid objectId, int subId, void *arg)
Definition: objectaccess.h:127
void RunObjectPostCreateHookStr(Oid classId, const char *objectName, int subId, bool is_internal)
Definition: objectaccess.c:158
PGDLLIMPORT object_access_hook_type object_access_hook
Definition: objectaccess.c:22
void(* object_access_hook_type_str)(ObjectAccessType access, Oid classId, const char *objectStr, int subId, void *arg)
Definition: objectaccess.h:133
ObjectAccessType
Definition: objectaccess.h:49
@ OAT_NAMESPACE_SEARCH
Definition: objectaccess.h:53
@ OAT_FUNCTION_EXECUTE
Definition: objectaccess.h:54
@ OAT_DROP
Definition: objectaccess.h:51
@ OAT_TRUNCATE
Definition: objectaccess.h:55
@ OAT_POST_ALTER
Definition: objectaccess.h:52
@ OAT_POST_CREATE
Definition: objectaccess.h:50
void RunObjectTruncateHook(Oid objectId)
Definition: objectaccess.c:76
void RunObjectPostAlterHookStr(Oid classId, const char *objectName, int subId, Oid auxiliaryId, bool is_internal)
Definition: objectaccess.c:218
void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId, bool is_internal)
Definition: objectaccess.c:32
void RunObjectDropHookStr(Oid classId, const char *objectName, int subId, int dropflags)
Definition: objectaccess.c:180
bool RunNamespaceSearchHookStr(const char *objectName, bool ereport_on_violation)
Definition: objectaccess.c:241
PGDLLIMPORT object_access_hook_type_str object_access_hook_str
Definition: objectaccess.c:23
void * arg
unsigned int Oid
Definition: postgres_ext.h:31
short access
Definition: preproc-type.c:36