From dd0ed26c6eb8ff454ce5faf0cc743b3a0d287c3c Mon Sep 17 00:00:00 2001 From: Joshua Brindle Date: Thu, 17 Mar 2022 09:24:57 -0700 Subject: [PATCH] Add String object access hooks The first user of these will be the GUC access controls Signed-off-by: Joshua Brindle --- src/backend/catalog/objectaccess.c | 128 +++++++++++++++++++++++++++++ src/backend/utils/misc/guc.c | 4 +- src/include/catalog/objectaccess.h | 70 +++++++++++++++- 3 files changed, 199 insertions(+), 3 deletions(-) diff --git a/src/backend/catalog/objectaccess.c b/src/backend/catalog/objectaccess.c index 549fac4539..72ad6e9a90 100644 --- a/src/backend/catalog/objectaccess.c +++ b/src/backend/catalog/objectaccess.c @@ -20,6 +20,8 @@ * and logging plugins. */ object_access_hook_type object_access_hook = NULL; +object_access_hook_type_str object_access_hook_str = NULL; + /* * RunObjectPostCreateHook @@ -143,3 +145,129 @@ RunFunctionExecuteHook(Oid objectId) ProcedureRelationId, objectId, 0, NULL); } + +/* String versions */ + + +/* + * RunObjectPostCreateHook + * + * It is entrypoint of OAT_POST_CREATE event + */ +void +RunObjectPostCreateHookStr(Oid classId, const char *objectName, int subId, + bool is_internal) +{ + ObjectAccessPostCreate pc_arg; + + /* caller should check, but just in case... */ + Assert(object_access_hook_str != NULL); + + memset(&pc_arg, 0, sizeof(ObjectAccessPostCreate)); + pc_arg.is_internal = is_internal; + + (*object_access_hook_str) (OAT_POST_CREATE, + classId, objectName, subId, + (void *) &pc_arg); +} + +/* + * RunObjectDropHook + * + * It is entrypoint of OAT_DROP event + */ +void +RunObjectDropHookStr(Oid classId, const char *objectName, int subId, + int dropflags) +{ + ObjectAccessDrop drop_arg; + + /* caller should check, but just in case... */ + Assert(object_access_hook_str != NULL); + + memset(&drop_arg, 0, sizeof(ObjectAccessDrop)); + drop_arg.dropflags = dropflags; + + (*object_access_hook_str) (OAT_DROP, + classId, objectName, subId, + (void *) &drop_arg); +} + +/* + * RunObjectTruncateHook + * + * It is the entrypoint of OAT_TRUNCATE event + */ +void +RunObjectTruncateHookStr(const char *objectName) +{ + /* caller should check, but just in case... */ + Assert(object_access_hook_str != NULL); + + (*object_access_hook_str) (OAT_TRUNCATE, + RelationRelationId, objectName, 0, + NULL); +} + +/* + * RunObjectPostAlterHook + * + * It is entrypoint of OAT_POST_ALTER event + */ +void +RunObjectPostAlterHookStr(Oid classId, const char *objectName, int subId, + Oid auxiliaryId, bool is_internal) +{ + ObjectAccessPostAlter pa_arg; + + /* caller should check, but just in case... */ + Assert(object_access_hook_str != NULL); + + memset(&pa_arg, 0, sizeof(ObjectAccessPostAlter)); + pa_arg.auxiliary_id = auxiliaryId; + pa_arg.is_internal = is_internal; + + (*object_access_hook_str) (OAT_POST_ALTER, + classId, objectName, subId, + (void *) &pa_arg); +} + +/* + * RunNamespaceSearchHook + * + * It is entrypoint of OAT_NAMESPACE_SEARCH event + */ +bool +RunNamespaceSearchHookStr(const char *objectName, bool ereport_on_violation) +{ + ObjectAccessNamespaceSearch ns_arg; + + /* caller should check, but just in case... */ + Assert(object_access_hook_str != NULL); + + memset(&ns_arg, 0, sizeof(ObjectAccessNamespaceSearch)); + ns_arg.ereport_on_violation = ereport_on_violation; + ns_arg.result = true; + + (*object_access_hook_str) (OAT_NAMESPACE_SEARCH, + NamespaceRelationId, objectName, 0, + (void *) &ns_arg); + + return ns_arg.result; +} + +/* + * RunFunctionExecuteHook + * + * It is entrypoint of OAT_FUNCTION_EXECUTE event + */ +void +RunFunctionExecuteHookStr(const char *objectName) +{ + /* caller should check, but just in case... */ + Assert(object_access_hook_str != NULL); + + (*object_access_hook_str) (OAT_FUNCTION_EXECUTE, + ProcedureRelationId, objectName, 0, + NULL); +} diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 683031db9a..8edee70394 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -8853,7 +8853,7 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt) * transactional. If the hook aborts our transaction, it will be cleaner * to do so before we touch any files. */ - InvokeObjectPostAlterHookArg(SettingAclRelationId, settingId, + InvokeObjectPostAlterHookArgStr(SettingAclRelationId, name, ACL_ALTER_SYSTEM, altersysstmt->setstmt->kind, false); @@ -9057,7 +9057,7 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel) * abuse the notion of subId to pass the kind of alteration (set vs. alter * system), and auxiliaryId to pass the VariableSetKind. */ - InvokeObjectPostAlterHookArg(SettingAclRelationId, settingId, + InvokeObjectPostAlterHookArgStr(SettingAclRelationId, stmt->name, ACL_SET_VALUE, stmt->kind, false); } diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h index 508dfd0a6b..4d54ae2a7d 100644 --- a/src/include/catalog/objectaccess.h +++ b/src/include/catalog/objectaccess.h @@ -121,15 +121,23 @@ typedef struct bool result; } ObjectAccessNamespaceSearch; -/* Plugin provides a hook function matching this signature. */ +/* Plugin provides a hook function matching one or both of these signatures. */ typedef void (*object_access_hook_type) (ObjectAccessType access, Oid classId, Oid objectId, int subId, void *arg); +typedef void (*object_access_hook_type_str) (ObjectAccessType access, + Oid classId, + const char *objectStr, + int subId, + void *arg); + /* Plugin sets this variable to a suitable hook function. */ extern PGDLLIMPORT object_access_hook_type object_access_hook; +extern PGDLLIMPORT object_access_hook_type_str object_access_hook_str; + /* Core code uses these functions to call the hook (see macros below). */ extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId, @@ -142,6 +150,18 @@ extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId, extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation); extern void RunFunctionExecuteHook(Oid objectId); +/* String versions */ +extern void RunObjectPostCreateHookStr(Oid classId, const char *objectStr, int subId, + bool is_internal); +extern void RunObjectDropHookStr(Oid classId, const char *objectStr, int subId, + int dropflags); +extern void RunObjectTruncateHookStr(const char *objectStr); +extern void RunObjectPostAlterHookStr(Oid classId, const char *objectStr, int subId, + Oid auxiliaryId, bool is_internal); +extern bool RunNamespaceSearchHookStr(const char *objectStr, bool ereport_on_violation); +extern void RunFunctionExecuteHookStr(const char *objectStr); + + /* * The following macros are wrappers around the functions above; these should * normally be used to invoke the hook in lieu of calling the above functions @@ -194,4 +214,52 @@ extern void RunFunctionExecuteHook(Oid objectId); RunFunctionExecuteHook(objectId); \ } while(0) + +#define InvokeObjectPostCreateHookStr(classId,objectName,subId) \ + InvokeObjectPostCreateHookArgStr((classId),(objectName),(subId),false) +#define InvokeObjectPostCreateHookArgStr(classId,objectName,subId,is_internal) \ + do { \ + if (object_access_hook_str) \ + RunObjectPostCreateHookStr((classId),(objectName),(subId), \ + (is_internal)); \ + } while(0) + +#define InvokeObjectDropHookStr(classId,objectName,subId) \ + InvokeObjectDropHookArgStr((classId),(objectName),(subId),0) +#define InvokeObjectDropHookArgStr(classId,objectName,subId,dropflags) \ + do { \ + if (object_access_hook_str) \ + RunObjectDropHookStr((classId),(objectName),(subId), \ + (dropflags)); \ + } while(0) + +#define InvokeObjectTruncateHookStr(objectName) \ + do { \ + if (object_access_hook_str) \ + RunObjectTruncateHookStr(objectName); \ + } while(0) + +#define InvokeObjectPostAlterHookStr(className,objectName,subId) \ + InvokeObjectPostAlterHookArgStr((classId),(objectName),(subId), \ + InvalidOid,false) +#define InvokeObjectPostAlterHookArgStr(classId,objectName,subId, \ + auxiliaryId,is_internal) \ + do { \ + if (object_access_hook_str) \ + RunObjectPostAlterHookStr((classId),(objectName),(subId), \ + (auxiliaryId),(is_internal)); \ + } while(0) + +#define InvokeNamespaceSearchHookStr(objectName, ereport_on_violation) \ + (!object_access_hook_str \ + ? true \ + : RunNamespaceSearchHookStr((objectName), (ereport_on_violation))) + +#define InvokeFunctionExecuteHookStr(objectName) \ + do { \ + if (object_access_hook_str) \ + RunFunctionExecuteHookStr(objectName); \ + } while(0) + + #endif /* OBJECTACCESS_H */ -- 2.35.1