objectaccess.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * objectaccess.h
  3. *
  4. * Object access hooks.
  5. *
  6. * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
  7. * Portions Copyright (c) 1994, Regents of the University of California
  8. */
  9. #ifndef OBJECTACCESS_H
  10. #define OBJECTACCESS_H
  11. /*
  12. * Object access hooks are intended to be called just before or just after
  13. * performing certain actions on a SQL object. This is intended as
  14. * infrastructure for security or logging plugins.
  15. *
  16. * OAT_POST_CREATE should be invoked just after the object is created.
  17. * Typically, this is done after inserting the primary catalog records and
  18. * associated dependencies.
  19. *
  20. * OAT_DROP should be invoked just before deletion of objects; typically
  21. * deleteOneObject(). Its arguments are packed within ObjectAccessDrop.
  22. *
  23. * OAT_POST_ALTER should be invoked just after the object is altered,
  24. * but before the command counter is incremented. An extension using the
  25. * hook can use a current MVCC snapshot to get the old version of the tuple,
  26. * and can use SnapshotSelf to get the new version of the tuple.
  27. *
  28. * OAT_NAMESPACE_SEARCH should be invoked prior to object name lookup under
  29. * a particular namespace. This event is equivalent to usage permission
  30. * on a schema under the default access control mechanism.
  31. *
  32. * OAT_FUNCTION_EXECUTE should be invoked prior to function execution.
  33. * This event is almost equivalent to execute permission on functions,
  34. * except for the case when execute permission is checked during object
  35. * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are
  36. * sufficient for extensions to track these kind of checks.
  37. *
  38. * Other types may be added in the future.
  39. */
  40. typedef enum ObjectAccessType
  41. {
  42. OAT_POST_CREATE,
  43. OAT_DROP,
  44. OAT_POST_ALTER,
  45. OAT_NAMESPACE_SEARCH,
  46. OAT_FUNCTION_EXECUTE
  47. } ObjectAccessType;
  48. /*
  49. * Arguments of OAT_POST_CREATE event
  50. */
  51. typedef struct
  52. {
  53. /*
  54. * This flag informs extensions whether the context of this creation is
  55. * invoked by user's operations, or not. E.g, it shall be dealt as
  56. * internal stuff on toast tables or indexes due to type changes.
  57. */
  58. bool is_internal;
  59. } ObjectAccessPostCreate;
  60. /*
  61. * Arguments of OAT_DROP event
  62. */
  63. typedef struct
  64. {
  65. /*
  66. * Flags to inform extensions the context of this deletion. Also see
  67. * PERFORM_DELETION_* in dependency.h
  68. */
  69. int dropflags;
  70. } ObjectAccessDrop;
  71. /*
  72. * Arguments of OAT_POST_ALTER event
  73. */
  74. typedef struct
  75. {
  76. /*
  77. * This identifier is used when system catalog takes two IDs to identify a
  78. * particular tuple of the catalog. It is only used when the caller want
  79. * to identify an entry of pg_inherits, pg_db_role_setting or
  80. * pg_user_mapping. Elsewhere, InvalidOid should be set.
  81. */
  82. Oid auxiliary_id;
  83. /*
  84. * If this flag is set, the user hasn't requested that the object be
  85. * altered, but we're doing it anyway for some internal reason.
  86. * Permissions-checking hooks may want to skip checks if, say, we're alter
  87. * the constraints of a temporary heap during CLUSTER.
  88. */
  89. bool is_internal;
  90. } ObjectAccessPostAlter;
  91. /*
  92. * Arguments of OAT_NAMESPACE_SEARCH
  93. */
  94. typedef struct
  95. {
  96. /*
  97. * If true, hook should report an error when permission to search this
  98. * schema is denied.
  99. */
  100. bool ereport_on_violation;
  101. /*
  102. * This is, in essence, an out parameter. Core code should initialize
  103. * this to true, and any extension that wants to deny access should reset
  104. * it to false. But an extension should be careful never to store a true
  105. * value here, so that in case there are multiple extensions access is
  106. * only allowed if all extensions agree.
  107. */
  108. bool result;
  109. } ObjectAccessNamespaceSearch;
  110. /* Plugin provides a hook function matching this signature. */
  111. typedef void (*object_access_hook_type) (ObjectAccessType access,
  112. Oid classId,
  113. Oid objectId,
  114. int subId,
  115. void *arg);
  116. /* Plugin sets this variable to a suitable hook function. */
  117. extern PGDLLIMPORT object_access_hook_type object_access_hook;
  118. /* Core code uses these functions to call the hook (see macros below). */
  119. extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
  120. bool is_internal);
  121. extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,
  122. int dropflags);
  123. extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
  124. Oid auxiliaryId, bool is_internal);
  125. extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_volation);
  126. extern void RunFunctionExecuteHook(Oid objectId);
  127. /*
  128. * The following macros are wrappers around the functions above; these should
  129. * normally be used to invoke the hook in lieu of calling the above functions
  130. * directly.
  131. */
  132. #define InvokeObjectPostCreateHook(classId,objectId,subId) \
  133. InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false)
  134. #define InvokeObjectPostCreateHookArg(classId,objectId,subId,is_internal) \
  135. do { \
  136. if (object_access_hook) \
  137. RunObjectPostCreateHook((classId),(objectId),(subId), \
  138. (is_internal)); \
  139. } while(0)
  140. #define InvokeObjectDropHook(classId,objectId,subId) \
  141. InvokeObjectDropHookArg((classId),(objectId),(subId),0)
  142. #define InvokeObjectDropHookArg(classId,objectId,subId,dropflags) \
  143. do { \
  144. if (object_access_hook) \
  145. RunObjectDropHook((classId),(objectId),(subId), \
  146. (dropflags)); \
  147. } while(0)
  148. #define InvokeObjectPostAlterHook(classId,objectId,subId) \
  149. InvokeObjectPostAlterHookArg((classId),(objectId),(subId), \
  150. InvalidOid,false)
  151. #define InvokeObjectPostAlterHookArg(classId,objectId,subId, \
  152. auxiliaryId,is_internal) \
  153. do { \
  154. if (object_access_hook) \
  155. RunObjectPostAlterHook((classId),(objectId),(subId), \
  156. (auxiliaryId),(is_internal)); \
  157. } while(0)
  158. #define InvokeNamespaceSearchHook(objectId, ereport_on_violation) \
  159. (!object_access_hook \
  160. ? true \
  161. : RunNamespaceSearchHook((objectId), (ereport_on_violation)))
  162. #define InvokeFunctionExecuteHook(objectId) \
  163. do { \
  164. if (object_access_hook) \
  165. RunFunctionExecuteHook(objectId); \
  166. } while(0)
  167. #endif /* OBJECTACCESS_H */