]> granicus.if.org Git - postgresql/blob - src/include/catalog/objectaccess.h
Phase 2 of pgindent updates.
[postgresql] / src / include / catalog / objectaccess.h
1 /*
2  * objectaccess.h
3  *
4  *              Object access hooks.
5  *
6  * Portions Copyright (c) 1996-2017, 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.
21  *
22  * OAT_DROP should be invoked just before deletion of objects; typically
23  * deleteOneObject(). Its arguments are packed within ObjectAccessDrop.
24  *
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.
29  *
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.
33  *
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.
39  *
40  * Other types may be added in the future.
41  */
42 typedef enum ObjectAccessType
43 {
44         OAT_POST_CREATE,
45         OAT_DROP,
46         OAT_POST_ALTER,
47         OAT_NAMESPACE_SEARCH,
48         OAT_FUNCTION_EXECUTE
49 } ObjectAccessType;
50
51 /*
52  * Arguments of OAT_POST_CREATE event
53  */
54 typedef struct
55 {
56         /*
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.
60          */
61         bool            is_internal;
62 } ObjectAccessPostCreate;
63
64 /*
65  * Arguments of OAT_DROP event
66  */
67 typedef struct
68 {
69         /*
70          * Flags to inform extensions the context of this deletion. Also see
71          * PERFORM_DELETION_* in dependency.h
72          */
73         int                     dropflags;
74 } ObjectAccessDrop;
75
76 /*
77  * Arguments of OAT_POST_ALTER event
78  */
79 typedef struct
80 {
81         /*
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.
86          */
87         Oid                     auxiliary_id;
88
89         /*
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.
94          */
95         bool            is_internal;
96 } ObjectAccessPostAlter;
97
98 /*
99  * Arguments of OAT_NAMESPACE_SEARCH
100  */
101 typedef struct
102 {
103         /*
104          * If true, hook should report an error when permission to search this
105          * schema is denied.
106          */
107         bool            ereport_on_violation;
108
109         /*
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.
115          */
116         bool            result;
117 } ObjectAccessNamespaceSearch;
118
119 /* Plugin provides a hook function matching this signature. */
120 typedef void (*object_access_hook_type) (ObjectAccessType access,
121                                                                                  Oid classId,
122                                                                                  Oid objectId,
123                                                                                  int subId,
124                                                                                  void *arg);
125
126 /* Plugin sets this variable to a suitable hook function. */
127 extern PGDLLIMPORT object_access_hook_type object_access_hook;
128
129 /* Core code uses these functions to call the hook (see macros below). */
130 extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
131                                                 bool is_internal);
132 extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,
133                                   int dropflags);
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);
138
139 /*
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
142  * directly.
143  */
144
145 #define InvokeObjectPostCreateHook(classId,objectId,subId)                      \
146         InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false)
147 #define InvokeObjectPostCreateHookArg(classId,objectId,subId,is_internal) \
148         do {                                                                                                                    \
149                 if (object_access_hook)                                                                         \
150                         RunObjectPostCreateHook((classId),(objectId),(subId),   \
151                                                                         (is_internal));                                 \
152         } while(0)
153
154 #define InvokeObjectDropHook(classId,objectId,subId)                            \
155         InvokeObjectDropHookArg((classId),(objectId),(subId),0)
156 #define InvokeObjectDropHookArg(classId,objectId,subId,dropflags)       \
157         do {                                                                                                                    \
158                 if (object_access_hook)                                                                         \
159                         RunObjectDropHook((classId),(objectId),(subId),                 \
160                                                           (dropflags));                                                 \
161         } while(0)
162
163 #define InvokeObjectPostAlterHook(classId,objectId,subId)                       \
164         InvokeObjectPostAlterHookArg((classId),(objectId),(subId),              \
165                                                                  InvalidOid,false)
166 #define InvokeObjectPostAlterHookArg(classId,objectId,subId,            \
167                                                                          auxiliaryId,is_internal)               \
168         do {                                                                                                                    \
169                 if (object_access_hook)                                                                         \
170                         RunObjectPostAlterHook((classId),(objectId),(subId),    \
171                                                                    (auxiliaryId),(is_internal));        \
172         } while(0)
173
174 #define InvokeNamespaceSearchHook(objectId, ereport_on_violation)       \
175         (!object_access_hook                                                                                    \
176          ? true                                                                                                                 \
177          : RunNamespaceSearchHook((objectId), (ereport_on_violation)))
178
179 #define InvokeFunctionExecuteHook(objectId)             \
180         do {                                                                            \
181                 if (object_access_hook)                                 \
182                         RunFunctionExecuteHook(objectId);       \
183         } while(0)
184
185 #endif                                                  /* OBJECTACCESS_H */