Header And Logo

PostgreSQL
| The world's most advanced open source database.

objectaccess.h

Go to the documentation of this file.
00001 /*
00002  * objectaccess.h
00003  *
00004  *      Object access hooks.
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  */
00009 
00010 #ifndef OBJECTACCESS_H
00011 #define OBJECTACCESS_H
00012 
00013 /*
00014  * Object access hooks are intended to be called just before or just after
00015  * performing certain actions on a SQL object.  This is intended as
00016  * infrastructure for security or logging pluggins.
00017  *
00018  * OAT_POST_CREATE should be invoked just after the object is created.
00019  * Typically, this is done after inserting the primary catalog records and
00020  * associated dependencies.
00021  *
00022  * OAT_DROP should be invoked just before deletion of objects; typically
00023  * deleteOneObject(). Its arguments are packed within ObjectAccessDrop.
00024  *
00025  * OAT_POST_ALTER should be invoked just after the object is altered,
00026  * but before the command counter is incremented.  An extension using the
00027  * hook can use SnapshotNow and SnapshotSelf to get the old and new
00028  * versions of the tuple.
00029  *
00030  * OAT_NAMESPACE_SEARCH should be invoked prior to object name lookup under
00031  * a particular namespace. This event is equivalent to usage permission
00032  * on a schema under the default access control mechanism.
00033  *
00034  * OAT_FUNCTION_EXECUTE should be invoked prior to function execution.
00035  * This event is almost equivalent to execute permission on functions,
00036  * except for the case when execute permission is checked during object
00037  * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are
00038  * sufficient for extensions to track these kind of checks.
00039  *
00040  * Other types may be added in the future.
00041  */
00042 typedef enum ObjectAccessType
00043 {
00044     OAT_POST_CREATE,
00045     OAT_DROP,
00046     OAT_POST_ALTER,
00047     OAT_NAMESPACE_SEARCH,
00048     OAT_FUNCTION_EXECUTE,
00049 } ObjectAccessType;
00050 
00051 /*
00052  * Arguments of OAT_POST_CREATE event
00053  */
00054 typedef struct
00055 {
00056     /*
00057      * This flag informs extensions whether the context of this creation
00058      * is invoked by user's operations, or not. E.g, it shall be dealt
00059      * as internal stuff on toast tables or indexes due to type changes.
00060      */
00061     bool        is_internal;
00062 } ObjectAccessPostCreate;
00063 
00064 /*
00065  * Arguments of OAT_DROP event
00066  */
00067 typedef struct
00068 {
00069     /*
00070      * Flags to inform extensions the context of this deletion. Also see
00071      * PERFORM_DELETION_* in dependency.h
00072      */
00073     int         dropflags;
00074 } ObjectAccessDrop;
00075 
00076 /*
00077  * Arguments of OAT_POST_ALTER event
00078  */
00079 typedef struct
00080 {
00081     /*
00082      * This identifier is used when system catalog takes two IDs
00083      * to identify a particular tuple of the catalog.
00084      * It is only used when the caller want to identify an entry
00085      * of pg_inherits, pg_db_role_setting or pg_user_mapping.
00086      * Elsewhere, InvalidOid should be set.
00087      */
00088     Oid         auxiliary_id;
00089 
00090     /*
00091      * If this flag is set, the user hasn't requested that the object be
00092      * altered, but we're doing it anyway for some internal reason.
00093      * Permissions-checking hooks may want to skip checks if, say, we're
00094      * alter the constraints of a temporary heap during CLUSTER.
00095      */
00096     bool        is_internal;
00097 } ObjectAccessPostAlter;
00098 
00099 /*
00100  * Arguments of OAT_NAMESPACE_SEARCH
00101  */
00102 typedef struct
00103 {
00104     /*
00105      * If true, hook should report an error when permission to search this
00106      * schema is denied.
00107      */
00108     bool        ereport_on_violation;
00109 
00110     /*
00111      * This is, in essence, an out parameter.  Core code should
00112      * initialize this to true, and any extension that wants to deny
00113      * access should reset it to false.  But an extension should be
00114      * careful never to store a true value here, so that in case there are
00115      * multiple extensions access is only allowed if all extensions
00116      * agree.
00117      */
00118     bool        result;
00119 } ObjectAccessNamespaceSearch;
00120 
00121 /* Plugin provides a hook function matching this signature. */
00122 typedef void (*object_access_hook_type) (ObjectAccessType access,
00123                                                      Oid classId,
00124                                                      Oid objectId,
00125                                                      int subId,
00126                                                      void *arg);
00127 
00128 /* Plugin sets this variable to a suitable hook function. */
00129 extern PGDLLIMPORT object_access_hook_type object_access_hook;
00130 
00131 /* Core code uses these functions to call the hook (see macros below). */
00132 extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
00133                                     bool is_internal);
00134 extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,
00135                               int dropflags);
00136 extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
00137                                    Oid auxiliaryId, bool is_internal);
00138 extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_volation);
00139 extern void RunFunctionExecuteHook(Oid objectId);
00140 
00141 /*
00142  * The following macros are wrappers around the functions above; these should
00143  * normally be used to invoke the hook in lieu of calling the above functions
00144  * directly.
00145  */
00146 
00147 #define InvokeObjectPostCreateHook(classId,objectId,subId)          \
00148     InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false)
00149 #define InvokeObjectPostCreateHookArg(classId,objectId,subId,is_internal) \
00150     do {                                                            \
00151         if (object_access_hook)                                     \
00152             RunObjectPostCreateHook((classId),(objectId),(subId),   \
00153                                     (is_internal));                 \
00154     } while(0)
00155 
00156 #define InvokeObjectDropHook(classId,objectId,subId)                \
00157     InvokeObjectDropHookArg((classId),(objectId),(subId),0)
00158 #define InvokeObjectDropHookArg(classId,objectId,subId,dropflags)   \
00159     do {                                                            \
00160         if (object_access_hook)                                     \
00161             RunObjectDropHook((classId),(objectId),(subId),         \
00162                               (dropflags));                         \
00163     } while(0)
00164 
00165 #define InvokeObjectPostAlterHook(classId,objectId,subId)           \
00166     InvokeObjectPostAlterHookArg((classId),(objectId),(subId),      \
00167                                  InvalidOid,false)
00168 #define InvokeObjectPostAlterHookArg(classId,objectId,subId,        \
00169                                      auxiliaryId,is_internal)       \
00170     do {                                                            \
00171         if (object_access_hook)                                     \
00172             RunObjectPostAlterHook((classId),(objectId),(subId),    \
00173                                    (auxiliaryId),(is_internal));    \
00174     } while(0)
00175 
00176 #define InvokeNamespaceSearchHook(objectId, ereport_on_violation)   \
00177     (!object_access_hook                                            \
00178      ? true                                                         \
00179      : RunNamespaceSearchHook((objectId), (ereport_on_violation)))
00180 
00181 #define InvokeFunctionExecuteHook(objectId)     \
00182     do {                                        \
00183         if (object_access_hook)                 \
00184             RunFunctionExecuteHook(objectId);   \
00185     } while(0)
00186 
00187 #endif   /* OBJECTACCESS_H */