Skip to content

Commit d11e84e

Browse files
committed
Add String object access hooks
This caters for cases where the access is to an object identified by name rather than Oid. The first user of these is the GUC access controls Joshua Brindle and Mark Dilger Discussion: https://postgr.es/m/47F87A0E-C0E5-43A6-89F6-D403F2B45175@enterprisedb.com
1 parent 29992a6 commit d11e84e

File tree

5 files changed

+226
-9
lines changed

5 files changed

+226
-9
lines changed

src/backend/catalog/objectaccess.c

+134-6
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
* and logging plugins.
2121
*/
2222
object_access_hook_type object_access_hook = NULL;
23+
object_access_hook_type_str object_access_hook_str = NULL;
24+
2325

2426
/*
2527
* RunObjectPostCreateHook
2628
*
27-
* It is entrypoint of OAT_POST_CREATE event
29+
* OAT_POST_CREATE object ID based event hook entrypoint
2830
*/
2931
void
3032
RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
@@ -46,7 +48,7 @@ RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
4648
/*
4749
* RunObjectDropHook
4850
*
49-
* It is entrypoint of OAT_DROP event
51+
* OAT_DROP object ID based event hook entrypoint
5052
*/
5153
void
5254
RunObjectDropHook(Oid classId, Oid objectId, int subId,
@@ -68,7 +70,7 @@ RunObjectDropHook(Oid classId, Oid objectId, int subId,
6870
/*
6971
* RunObjectTruncateHook
7072
*
71-
* It is the entrypoint of OAT_TRUNCATE event
73+
* OAT_TRUNCATE object ID based event hook entrypoint
7274
*/
7375
void
7476
RunObjectTruncateHook(Oid objectId)
@@ -84,7 +86,7 @@ RunObjectTruncateHook(Oid objectId)
8486
/*
8587
* RunObjectPostAlterHook
8688
*
87-
* It is entrypoint of OAT_POST_ALTER event
89+
* OAT_POST_ALTER object ID based event hook entrypoint
8890
*/
8991
void
9092
RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
@@ -107,7 +109,7 @@ RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
107109
/*
108110
* RunNamespaceSearchHook
109111
*
110-
* It is entrypoint of OAT_NAMESPACE_SEARCH event
112+
* OAT_NAMESPACE_SEARCH object ID based event hook entrypoint
111113
*/
112114
bool
113115
RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
@@ -131,7 +133,7 @@ RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
131133
/*
132134
* RunFunctionExecuteHook
133135
*
134-
* It is entrypoint of OAT_FUNCTION_EXECUTE event
136+
* OAT_FUNCTION_EXECUTE object ID based event hook entrypoint
135137
*/
136138
void
137139
RunFunctionExecuteHook(Oid objectId)
@@ -143,3 +145,129 @@ RunFunctionExecuteHook(Oid objectId)
143145
ProcedureRelationId, objectId, 0,
144146
NULL);
145147
}
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+
{
161+
ObjectAccessPostCreate pc_arg;
162+
163+
/* caller should check, but just in case... */
164+
Assert(object_access_hook_str != NULL);
165+
166+
memset(&pc_arg, 0, sizeof(ObjectAccessPostCreate));
167+
pc_arg.is_internal = is_internal;
168+
169+
(*object_access_hook_str) (OAT_POST_CREATE,
170+
classId, objectName, subId,
171+
(void *) &pc_arg);
172+
}
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+
{
183+
ObjectAccessDrop drop_arg;
184+
185+
/* caller should check, but just in case... */
186+
Assert(object_access_hook_str != NULL);
187+
188+
memset(&drop_arg, 0, sizeof(ObjectAccessDrop));
189+
drop_arg.dropflags = dropflags;
190+
191+
(*object_access_hook_str) (OAT_DROP,
192+
classId, objectName, subId,
193+
(void *) &drop_arg);
194+
}
195+
196+
/*
197+
* RunObjectTruncateHookStr
198+
*
199+
* OAT_TRUNCATE object name based event hook entrypoint
200+
*/
201+
void
202+
RunObjectTruncateHookStr(const char *objectName)
203+
{
204+
/* caller should check, but just in case... */
205+
Assert(object_access_hook_str != NULL);
206+
207+
(*object_access_hook_str) (OAT_TRUNCATE,
208+
RelationRelationId, objectName, 0,
209+
NULL);
210+
}
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+
{
221+
ObjectAccessPostAlter pa_arg;
222+
223+
/* caller should check, but just in case... */
224+
Assert(object_access_hook_str != NULL);
225+
226+
memset(&pa_arg, 0, sizeof(ObjectAccessPostAlter));
227+
pa_arg.auxiliary_id = auxiliaryId;
228+
pa_arg.is_internal = is_internal;
229+
230+
(*object_access_hook_str) (OAT_POST_ALTER,
231+
classId, objectName, subId,
232+
(void *) &pa_arg);
233+
}
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+
{
243+
ObjectAccessNamespaceSearch ns_arg;
244+
245+
/* caller should check, but just in case... */
246+
Assert(object_access_hook_str != NULL);
247+
248+
memset(&ns_arg, 0, sizeof(ObjectAccessNamespaceSearch));
249+
ns_arg.ereport_on_violation = ereport_on_violation;
250+
ns_arg.result = true;
251+
252+
(*object_access_hook_str) (OAT_NAMESPACE_SEARCH,
253+
NamespaceRelationId, objectName, 0,
254+
(void *) &ns_arg);
255+
256+
return ns_arg.result;
257+
}
258+
259+
/*
260+
* RunFunctionExecuteHookStr
261+
*
262+
* OAT_FUNCTION_EXECUTE object name based event hook entrypoint
263+
*/
264+
void
265+
RunFunctionExecuteHookStr(const char *objectName)
266+
{
267+
/* caller should check, but just in case... */
268+
Assert(object_access_hook_str != NULL);
269+
270+
(*object_access_hook_str) (OAT_FUNCTION_EXECUTE,
271+
ProcedureRelationId, objectName, 0,
272+
NULL);
273+
}

src/backend/utils/misc/guc.c

+17
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "access/xlog_internal.h"
4444
#include "access/xlogrecovery.h"
4545
#include "catalog/namespace.h"
46+
#include "catalog/objectaccess.h"
4647
#include "catalog/pg_authid.h"
4748
#include "catalog/storage.h"
4849
#include "commands/async.h"
@@ -8736,6 +8737,18 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
87368737
replace_auto_config_value(&head, &tail, name, value);
87378738
}
87388739

8740+
/*
8741+
* Invoke the post-alter hook for altering this GUC variable.
8742+
*
8743+
* We do this here rather than at the end, because ALTER SYSTEM is not
8744+
* transactional. If the hook aborts our transaction, it will be cleaner
8745+
* to do so before we touch any files.
8746+
*/
8747+
InvokeObjectPostAlterHookArgStr(InvalidOid, name,
8748+
ACL_ALTER_SYSTEM,
8749+
altersysstmt->setstmt->kind,
8750+
false);
8751+
87398752
/*
87408753
* To ensure crash safety, first write the new file data to a temp file,
87418754
* then atomically rename it into place.
@@ -8907,6 +8920,10 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
89078920
ResetAllOptions();
89088921
break;
89098922
}
8923+
8924+
/* Invoke the post-alter hook for setting this GUC variable. */
8925+
InvokeObjectPostAlterHookArgStr(InvalidOid, stmt->name,
8926+
ACL_SET_VALUE, stmt->kind, false);
89108927
}
89118928

89128929
/*

src/include/catalog/objectaccess.h

+69-1
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,23 @@ typedef struct
121121
bool result;
122122
} ObjectAccessNamespaceSearch;
123123

124-
/* Plugin provides a hook function matching this signature. */
124+
/* Plugin provides a hook function matching one or both of these signatures. */
125125
typedef void (*object_access_hook_type) (ObjectAccessType access,
126126
Oid classId,
127127
Oid objectId,
128128
int subId,
129129
void *arg);
130130

131+
typedef void (*object_access_hook_type_str) (ObjectAccessType access,
132+
Oid classId,
133+
const char *objectStr,
134+
int subId,
135+
void *arg);
136+
131137
/* Plugin sets this variable to a suitable hook function. */
132138
extern PGDLLIMPORT object_access_hook_type object_access_hook;
139+
extern PGDLLIMPORT object_access_hook_type_str object_access_hook_str;
140+
133141

134142
/* Core code uses these functions to call the hook (see macros below). */
135143
extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
@@ -142,6 +150,18 @@ extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
142150
extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation);
143151
extern void RunFunctionExecuteHook(Oid objectId);
144152

153+
/* String versions */
154+
extern void RunObjectPostCreateHookStr(Oid classId, const char *objectStr, int subId,
155+
bool is_internal);
156+
extern void RunObjectDropHookStr(Oid classId, const char *objectStr, int subId,
157+
int dropflags);
158+
extern void RunObjectTruncateHookStr(const char *objectStr);
159+
extern void RunObjectPostAlterHookStr(Oid classId, const char *objectStr, int subId,
160+
Oid auxiliaryId, bool is_internal);
161+
extern bool RunNamespaceSearchHookStr(const char *objectStr, bool ereport_on_violation);
162+
extern void RunFunctionExecuteHookStr(const char *objectStr);
163+
164+
145165
/*
146166
* The following macros are wrappers around the functions above; these should
147167
* normally be used to invoke the hook in lieu of calling the above functions
@@ -194,4 +214,52 @@ extern void RunFunctionExecuteHook(Oid objectId);
194214
RunFunctionExecuteHook(objectId); \
195215
} while(0)
196216

217+
218+
#define InvokeObjectPostCreateHookStr(classId,objectName,subId) \
219+
InvokeObjectPostCreateHookArgStr((classId),(objectName),(subId),false)
220+
#define InvokeObjectPostCreateHookArgStr(classId,objectName,subId,is_internal) \
221+
do { \
222+
if (object_access_hook_str) \
223+
RunObjectPostCreateHookStr((classId),(objectName),(subId), \
224+
(is_internal)); \
225+
} while(0)
226+
227+
#define InvokeObjectDropHookStr(classId,objectName,subId) \
228+
InvokeObjectDropHookArgStr((classId),(objectName),(subId),0)
229+
#define InvokeObjectDropHookArgStr(classId,objectName,subId,dropflags) \
230+
do { \
231+
if (object_access_hook_str) \
232+
RunObjectDropHookStr((classId),(objectName),(subId), \
233+
(dropflags)); \
234+
} while(0)
235+
236+
#define InvokeObjectTruncateHookStr(objectName) \
237+
do { \
238+
if (object_access_hook_str) \
239+
RunObjectTruncateHookStr(objectName); \
240+
} while(0)
241+
242+
#define InvokeObjectPostAlterHookStr(className,objectName,subId) \
243+
InvokeObjectPostAlterHookArgStr((classId),(objectName),(subId), \
244+
InvalidOid,false)
245+
#define InvokeObjectPostAlterHookArgStr(classId,objectName,subId, \
246+
auxiliaryId,is_internal) \
247+
do { \
248+
if (object_access_hook_str) \
249+
RunObjectPostAlterHookStr((classId),(objectName),(subId), \
250+
(auxiliaryId),(is_internal)); \
251+
} while(0)
252+
253+
#define InvokeNamespaceSearchHookStr(objectName, ereport_on_violation) \
254+
(!object_access_hook_str \
255+
? true \
256+
: RunNamespaceSearchHookStr((objectName), (ereport_on_violation)))
257+
258+
#define InvokeFunctionExecuteHookStr(objectName) \
259+
do { \
260+
if (object_access_hook_str) \
261+
RunFunctionExecuteHookStr(objectName); \
262+
} while(0)
263+
264+
197265
#endif /* OBJECTACCESS_H */

src/include/nodes/parsenodes.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */
9292
#define ACL_CREATE (1<<9) /* for namespaces and databases */
9393
#define ACL_CREATE_TEMP (1<<10) /* for databases */
9494
#define ACL_CONNECT (1<<11) /* for databases */
95-
#define N_ACL_RIGHTS 12 /* 1 plus the last 1<<x */
95+
#define ACL_SET_VALUE (1<<12) /* for configuration parameters */
96+
#define ACL_ALTER_SYSTEM (1<<13) /* for configuration parameters */
97+
#define N_ACL_RIGHTS 14 /* 1 plus the last 1<<x */
9698
#define ACL_NO_RIGHTS 0
9799
/* Currently, SELECT ... FOR [KEY] UPDATE/SHARE requires UPDATE privileges */
98100
#define ACL_SELECT_FOR_UPDATE ACL_UPDATE

src/include/utils/acl.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,11 @@ typedef struct ArrayType Acl;
146146
#define ACL_CREATE_CHR 'C'
147147
#define ACL_CREATE_TEMP_CHR 'T'
148148
#define ACL_CONNECT_CHR 'c'
149+
#define ACL_SET_VALUE_CHR 's'
150+
#define ACL_ALTER_SYSTEM_CHR 'A'
149151

150152
/* string holding all privilege code chars, in order by bitmask position */
151-
#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTc"
153+
#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTcsA"
152154

153155
/*
154156
* Bitmasks defining "all rights" for each supported object type

0 commit comments

Comments
 (0)