Coverage Report

Created: 2025-08-12 06:43

/src/postgres/src/backend/catalog/objectaccess.c
Line
Count
Source (jump to first uncovered line)
1
/* -------------------------------------------------------------------------
2
 *
3
 * objectaccess.c
4
 *    functions for object_access_hook on various events
5
 *
6
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7
 * Portions Copyright (c) 1994, Regents of the University of California
8
 *
9
 * -------------------------------------------------------------------------
10
 */
11
#include "postgres.h"
12
13
#include "catalog/objectaccess.h"
14
#include "catalog/pg_class.h"
15
#include "catalog/pg_namespace.h"
16
#include "catalog/pg_proc.h"
17
18
/*
19
 * Hook on object accesses.  This is intended as infrastructure for security
20
 * and logging plugins.
21
 */
22
object_access_hook_type object_access_hook = NULL;
23
object_access_hook_type_str object_access_hook_str = NULL;
24
25
26
/*
27
 * RunObjectPostCreateHook
28
 *
29
 * OAT_POST_CREATE object ID based event hook entrypoint
30
 */
31
void
32
RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
33
            bool is_internal)
34
0
{
35
0
  ObjectAccessPostCreate pc_arg;
36
37
  /* caller should check, but just in case... */
38
0
  Assert(object_access_hook != NULL);
39
40
0
  memset(&pc_arg, 0, sizeof(ObjectAccessPostCreate));
41
0
  pc_arg.is_internal = is_internal;
42
43
0
  (*object_access_hook) (OAT_POST_CREATE,
44
0
               classId, objectId, subId,
45
0
               &pc_arg);
46
0
}
47
48
/*
49
 * RunObjectDropHook
50
 *
51
 * OAT_DROP object ID based event hook entrypoint
52
 */
53
void
54
RunObjectDropHook(Oid classId, Oid objectId, int subId,
55
          int dropflags)
56
0
{
57
0
  ObjectAccessDrop drop_arg;
58
59
  /* caller should check, but just in case... */
60
0
  Assert(object_access_hook != NULL);
61
62
0
  memset(&drop_arg, 0, sizeof(ObjectAccessDrop));
63
0
  drop_arg.dropflags = dropflags;
64
65
0
  (*object_access_hook) (OAT_DROP,
66
0
               classId, objectId, subId,
67
0
               &drop_arg);
68
0
}
69
70
/*
71
 * RunObjectTruncateHook
72
 *
73
 * OAT_TRUNCATE object ID based event hook entrypoint
74
 */
75
void
76
RunObjectTruncateHook(Oid objectId)
77
0
{
78
  /* caller should check, but just in case... */
79
0
  Assert(object_access_hook != NULL);
80
81
0
  (*object_access_hook) (OAT_TRUNCATE,
82
0
               RelationRelationId, objectId, 0,
83
0
               NULL);
84
0
}
85
86
/*
87
 * RunObjectPostAlterHook
88
 *
89
 * OAT_POST_ALTER object ID based event hook entrypoint
90
 */
91
void
92
RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
93
             Oid auxiliaryId, bool is_internal)
94
0
{
95
0
  ObjectAccessPostAlter pa_arg;
96
97
  /* caller should check, but just in case... */
98
0
  Assert(object_access_hook != NULL);
99
100
0
  memset(&pa_arg, 0, sizeof(ObjectAccessPostAlter));
101
0
  pa_arg.auxiliary_id = auxiliaryId;
102
0
  pa_arg.is_internal = is_internal;
103
104
0
  (*object_access_hook) (OAT_POST_ALTER,
105
0
               classId, objectId, subId,
106
0
               &pa_arg);
107
0
}
108
109
/*
110
 * RunNamespaceSearchHook
111
 *
112
 * OAT_NAMESPACE_SEARCH object ID based event hook entrypoint
113
 */
114
bool
115
RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
116
0
{
117
0
  ObjectAccessNamespaceSearch ns_arg;
118
119
  /* caller should check, but just in case... */
120
0
  Assert(object_access_hook != NULL);
121
122
0
  memset(&ns_arg, 0, sizeof(ObjectAccessNamespaceSearch));
123
0
  ns_arg.ereport_on_violation = ereport_on_violation;
124
0
  ns_arg.result = true;
125
126
0
  (*object_access_hook) (OAT_NAMESPACE_SEARCH,
127
0
               NamespaceRelationId, objectId, 0,
128
0
               &ns_arg);
129
130
0
  return ns_arg.result;
131
0
}
132
133
/*
134
 * RunFunctionExecuteHook
135
 *
136
 * OAT_FUNCTION_EXECUTE object ID based event hook entrypoint
137
 */
138
void
139
RunFunctionExecuteHook(Oid objectId)
140
0
{
141
  /* caller should check, but just in case... */
142
0
  Assert(object_access_hook != NULL);
143
144
0
  (*object_access_hook) (OAT_FUNCTION_EXECUTE,
145
0
               ProcedureRelationId, objectId, 0,
146
0
               NULL);
147
0
}
148
149
/* String versions */
150
151
152
/*
153
 * RunObjectPostCreateHookStr
154
 *
155
 * OAT_POST_CREATE object name based event hook entrypoint
156
 */
157
void
158
RunObjectPostCreateHookStr(Oid classId, const char *objectName, int subId,
159
               bool is_internal)
160
0
{
161
0
  ObjectAccessPostCreate pc_arg;
162
163
  /* caller should check, but just in case... */
164
0
  Assert(object_access_hook_str != NULL);
165
166
0
  memset(&pc_arg, 0, sizeof(ObjectAccessPostCreate));
167
0
  pc_arg.is_internal = is_internal;
168
169
0
  (*object_access_hook_str) (OAT_POST_CREATE,
170
0
                 classId, objectName, subId,
171
0
                 &pc_arg);
172
0
}
173
174
/*
175
 * RunObjectDropHookStr
176
 *
177
 * OAT_DROP object name based event hook entrypoint
178
 */
179
void
180
RunObjectDropHookStr(Oid classId, const char *objectName, int subId,
181
           int dropflags)
182
0
{
183
0
  ObjectAccessDrop drop_arg;
184
185
  /* caller should check, but just in case... */
186
0
  Assert(object_access_hook_str != NULL);
187
188
0
  memset(&drop_arg, 0, sizeof(ObjectAccessDrop));
189
0
  drop_arg.dropflags = dropflags;
190
191
0
  (*object_access_hook_str) (OAT_DROP,
192
0
                 classId, objectName, subId,
193
0
                 &drop_arg);
194
0
}
195
196
/*
197
 * RunObjectTruncateHookStr
198
 *
199
 * OAT_TRUNCATE object name based event hook entrypoint
200
 */
201
void
202
RunObjectTruncateHookStr(const char *objectName)
203
0
{
204
  /* caller should check, but just in case... */
205
0
  Assert(object_access_hook_str != NULL);
206
207
0
  (*object_access_hook_str) (OAT_TRUNCATE,
208
0
                 RelationRelationId, objectName, 0,
209
0
                 NULL);
210
0
}
211
212
/*
213
 * RunObjectPostAlterHookStr
214
 *
215
 * OAT_POST_ALTER object name based event hook entrypoint
216
 */
217
void
218
RunObjectPostAlterHookStr(Oid classId, const char *objectName, int subId,
219
              Oid auxiliaryId, bool is_internal)
220
0
{
221
0
  ObjectAccessPostAlter pa_arg;
222
223
  /* caller should check, but just in case... */
224
0
  Assert(object_access_hook_str != NULL);
225
226
0
  memset(&pa_arg, 0, sizeof(ObjectAccessPostAlter));
227
0
  pa_arg.auxiliary_id = auxiliaryId;
228
0
  pa_arg.is_internal = is_internal;
229
230
0
  (*object_access_hook_str) (OAT_POST_ALTER,
231
0
                 classId, objectName, subId,
232
0
                 &pa_arg);
233
0
}
234
235
/*
236
 * RunNamespaceSearchHookStr
237
 *
238
 * OAT_NAMESPACE_SEARCH object name based event hook entrypoint
239
 */
240
bool
241
RunNamespaceSearchHookStr(const char *objectName, bool ereport_on_violation)
242
0
{
243
0
  ObjectAccessNamespaceSearch ns_arg;
244
245
  /* caller should check, but just in case... */
246
0
  Assert(object_access_hook_str != NULL);
247
248
0
  memset(&ns_arg, 0, sizeof(ObjectAccessNamespaceSearch));
249
0
  ns_arg.ereport_on_violation = ereport_on_violation;
250
0
  ns_arg.result = true;
251
252
0
  (*object_access_hook_str) (OAT_NAMESPACE_SEARCH,
253
0
                 NamespaceRelationId, objectName, 0,
254
0
                 &ns_arg);
255
256
0
  return ns_arg.result;
257
0
}
258
259
/*
260
 * RunFunctionExecuteHookStr
261
 *
262
 * OAT_FUNCTION_EXECUTE object name based event hook entrypoint
263
 */
264
void
265
RunFunctionExecuteHookStr(const char *objectName)
266
0
{
267
  /* caller should check, but just in case... */
268
0
  Assert(object_access_hook_str != NULL);
269
270
0
  (*object_access_hook_str) (OAT_FUNCTION_EXECUTE,
271
0
                 ProcedureRelationId, objectName, 0,
272
0
                 NULL);
273
0
}