codekingpro/portable-devtools
115k
1/*2 * objectaccess.h3 *4 * Object access hooks.5 *6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group7 * Portions Copyright (c) 1994, Regents of the University of California8 */9 10#ifndef OBJECTACCESS_H11#define OBJECTACCESS_H12 13/*14 * Object access hooks are intended to be called just before or just after15 * performing certain actions on a SQL object. This is intended as16 * 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 and20 * associated dependencies. The command counter may or may not be incremented21 * at the time the hook is invoked; if not, the extension can use SnapshotSelf22 * to get the new version of the tuple.23 *24 * OAT_DROP should be invoked just before deletion of objects; typically25 * 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 the29 * 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 under33 * a particular namespace. This event is equivalent to usage permission34 * 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 object39 * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are40 * sufficient for extensions to track these kind of checks.41 *42 * OAT_TRUNCATE should be invoked just before truncation of objects. This43 * event is equivalent to truncate permission on a relation under the44 * default access control mechanism.45 *46 * Other types may be added in the future.47 */48typedef enum ObjectAccessType49{50 OAT_POST_CREATE,51 OAT_DROP,52 OAT_POST_ALTER,53 OAT_NAMESPACE_SEARCH,54 OAT_FUNCTION_EXECUTE,55 OAT_TRUNCATE56} ObjectAccessType;57 58/*59 * Arguments of OAT_POST_CREATE event60 */61typedef struct62{63 /*64 * This flag informs extensions whether the context of this creation is65 * invoked by user's operations, or not. E.g, it shall be dealt as66 * internal stuff on toast tables or indexes due to type changes.67 */68 bool is_internal;69} ObjectAccessPostCreate;70 71/*72 * Arguments of OAT_DROP event73 */74typedef struct75{76 /*77 * Flags to inform extensions the context of this deletion. Also see78 * PERFORM_DELETION_* in dependency.h79 */80 int dropflags;81} ObjectAccessDrop;82 83/*84 * Arguments of OAT_POST_ALTER event85 */86typedef struct87{88 /*89 * This identifier is used when system catalog takes two IDs to identify a90 * particular tuple of the catalog. It is only used when the caller want91 * to identify an entry of pg_inherits, pg_db_role_setting or92 * pg_user_mapping. Elsewhere, InvalidOid should be set.93 */94 Oid auxiliary_id;95 96 /*97 * If this flag is set, the user hasn't requested that the object be98 * altered, but we're doing it anyway for some internal reason.99 * Permissions-checking hooks may want to skip checks if, say, we're alter100 * the constraints of a temporary heap during CLUSTER.101 */102 bool is_internal;103} ObjectAccessPostAlter;104 105/*106 * Arguments of OAT_NAMESPACE_SEARCH107 */108typedef struct109{110 /*111 * If true, hook should report an error when permission to search this112 * schema is denied.113 */114 bool ereport_on_violation;115 116 /*117 * This is, in essence, an out parameter. Core code should initialize118 * this to true, and any extension that wants to deny access should reset119 * it to false. But an extension should be careful never to store a true120 * value here, so that in case there are multiple extensions access is121 * only allowed if all extensions agree.122 */123 bool result;124} ObjectAccessNamespaceSearch;125 126/* Plugin provides a hook function matching one or both of these signatures. */127typedef void (*object_access_hook_type) (ObjectAccessType access,128 Oid classId,129 Oid objectId,130 int subId,131 void *arg);132 133typedef void (*object_access_hook_type_str) (ObjectAccessType access,134 Oid classId,135 const char *objectStr,136 int subId,137 void *arg);138 139/* Plugin sets this variable to a suitable hook function. */140extern PGDLLIMPORT object_access_hook_type object_access_hook;141extern PGDLLIMPORT object_access_hook_type_str object_access_hook_str;142 143 144/* Core code uses these functions to call the hook (see macros below). */145extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,146 bool is_internal);147extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,148 int dropflags);149extern void RunObjectTruncateHook(Oid objectId);150extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,151 Oid auxiliaryId, bool is_internal);152extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation);153extern void RunFunctionExecuteHook(Oid objectId);154 155/* String versions */156extern void RunObjectPostCreateHookStr(Oid classId, const char *objectName, int subId,157 bool is_internal);158extern void RunObjectDropHookStr(Oid classId, const char *objectName, int subId,159 int dropflags);160extern void RunObjectTruncateHookStr(const char *objectName);161extern void RunObjectPostAlterHookStr(Oid classId, const char *objectName, int subId,162 Oid auxiliaryId, bool is_internal);163extern bool RunNamespaceSearchHookStr(const char *objectName, bool ereport_on_violation);164extern void RunFunctionExecuteHookStr(const char *objectName);165 166 167/*168 * The following macros are wrappers around the functions above; these should169 * normally be used to invoke the hook in lieu of calling the above functions170 * 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 */268 