6 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 #ifndef OBJECTACCESS_H
11 #define OBJECTACCESS_H
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.
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.
22 * OAT_DROP should be invoked just before deletion of objects; typically
23 * deleteOneObject(). Its arguments are packed within ObjectAccessDrop.
25 * OAT_POST_ALTER should be invoked just after the object is altered,
26 * but before the command counter is incremented. An extension using the
27 * hook can use a current MVCC snapshot to get the old version of the tuple,
28 * and can use SnapshotSelf to get the new version of the tuple.
30 * OAT_NAMESPACE_SEARCH should be invoked prior to object name lookup under
31 * a particular namespace. This event is equivalent to usage permission
32 * on a schema under the default access control mechanism.
34 * OAT_FUNCTION_EXECUTE should be invoked prior to function execution.
35 * This event is almost equivalent to execute permission on functions,
36 * except for the case when execute permission is checked during object
37 * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are
38 * sufficient for extensions to track these kind of checks.
40 * Other types may be added in the future.
42 typedef enum ObjectAccessType
52 * Arguments of OAT_POST_CREATE event
57 * This flag informs extensions whether the context of this creation is
58 * invoked by user's operations, or not. E.g, it shall be dealt as
59 * internal stuff on toast tables or indexes due to type changes.
62 } ObjectAccessPostCreate;
65 * Arguments of OAT_DROP event
70 * Flags to inform extensions the context of this deletion. Also see
71 * PERFORM_DELETION_* in dependency.h
77 * Arguments of OAT_POST_ALTER event
82 * This identifier is used when system catalog takes two IDs to identify a
83 * particular tuple of the catalog. It is only used when the caller want
84 * to identify an entry of pg_inherits, pg_db_role_setting or
85 * pg_user_mapping. Elsewhere, InvalidOid should be set.
90 * If this flag is set, the user hasn't requested that the object be
91 * altered, but we're doing it anyway for some internal reason.
92 * Permissions-checking hooks may want to skip checks if, say, we're alter
93 * the constraints of a temporary heap during CLUSTER.
96 } ObjectAccessPostAlter;
99 * Arguments of OAT_NAMESPACE_SEARCH
104 * If true, hook should report an error when permission to search this
107 bool ereport_on_violation;
110 * This is, in essence, an out parameter. Core code should initialize
111 * this to true, and any extension that wants to deny access should reset
112 * it to false. But an extension should be careful never to store a true
113 * value here, so that in case there are multiple extensions access is
114 * only allowed if all extensions agree.
117 } ObjectAccessNamespaceSearch;
119 /* Plugin provides a hook function matching this signature. */
120 typedef void (*object_access_hook_type) (ObjectAccessType access,
126 /* Plugin sets this variable to a suitable hook function. */
127 extern PGDLLIMPORT object_access_hook_type object_access_hook;
129 /* Core code uses these functions to call the hook (see macros below). */
130 extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
132 extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,
134 extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
135 Oid auxiliaryId, bool is_internal);
136 extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_volation);
137 extern void RunFunctionExecuteHook(Oid objectId);
140 * The following macros are wrappers around the functions above; these should
141 * normally be used to invoke the hook in lieu of calling the above functions
145 #define InvokeObjectPostCreateHook(classId,objectId,subId) \
146 InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false)
147 #define InvokeObjectPostCreateHookArg(classId,objectId,subId,is_internal) \
149 if (object_access_hook) \
150 RunObjectPostCreateHook((classId),(objectId),(subId), \
154 #define InvokeObjectDropHook(classId,objectId,subId) \
155 InvokeObjectDropHookArg((classId),(objectId),(subId),0)
156 #define InvokeObjectDropHookArg(classId,objectId,subId,dropflags) \
158 if (object_access_hook) \
159 RunObjectDropHook((classId),(objectId),(subId), \
163 #define InvokeObjectPostAlterHook(classId,objectId,subId) \
164 InvokeObjectPostAlterHookArg((classId),(objectId),(subId), \
166 #define InvokeObjectPostAlterHookArg(classId,objectId,subId, \
167 auxiliaryId,is_internal) \
169 if (object_access_hook) \
170 RunObjectPostAlterHook((classId),(objectId),(subId), \
171 (auxiliaryId),(is_internal)); \
174 #define InvokeNamespaceSearchHook(objectId, ereport_on_violation) \
175 (!object_access_hook \
177 : RunNamespaceSearchHook((objectId), (ereport_on_violation)))
179 #define InvokeFunctionExecuteHook(objectId) \
181 if (object_access_hook) \
182 RunFunctionExecuteHook(objectId); \
185 #endif /* OBJECTACCESS_H */