aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/catalog/objectaccess.c140
-rw-r--r--src/backend/utils/misc/guc.c17
-rw-r--r--src/include/catalog/objectaccess.h70
-rw-r--r--src/include/nodes/parsenodes.h4
-rw-r--r--src/include/utils/acl.h4
5 files changed, 226 insertions, 9 deletions
diff --git a/src/backend/catalog/objectaccess.c b/src/backend/catalog/objectaccess.c
index 549fac45392..38922294e28 100644
--- a/src/backend/catalog/objectaccess.c
+++ b/src/backend/catalog/objectaccess.c
@@ -20,11 +20,13 @@
* and logging plugins.
*/
object_access_hook_type object_access_hook = NULL;
+object_access_hook_type_str object_access_hook_str = NULL;
+
/*
* RunObjectPostCreateHook
*
- * It is entrypoint of OAT_POST_CREATE event
+ * OAT_POST_CREATE object ID based event hook entrypoint
*/
void
RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
@@ -46,7 +48,7 @@ RunObjectPostCreateHook(Oid classId, Oid objectId, int subId,
/*
* RunObjectDropHook
*
- * It is entrypoint of OAT_DROP event
+ * OAT_DROP object ID based event hook entrypoint
*/
void
RunObjectDropHook(Oid classId, Oid objectId, int subId,
@@ -68,7 +70,7 @@ RunObjectDropHook(Oid classId, Oid objectId, int subId,
/*
* RunObjectTruncateHook
*
- * It is the entrypoint of OAT_TRUNCATE event
+ * OAT_TRUNCATE object ID based event hook entrypoint
*/
void
RunObjectTruncateHook(Oid objectId)
@@ -84,7 +86,7 @@ RunObjectTruncateHook(Oid objectId)
/*
* RunObjectPostAlterHook
*
- * It is entrypoint of OAT_POST_ALTER event
+ * OAT_POST_ALTER object ID based event hook entrypoint
*/
void
RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
@@ -107,7 +109,7 @@ RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
/*
* RunNamespaceSearchHook
*
- * It is entrypoint of OAT_NAMESPACE_SEARCH event
+ * OAT_NAMESPACE_SEARCH object ID based event hook entrypoint
*/
bool
RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
@@ -131,7 +133,7 @@ RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
/*
* RunFunctionExecuteHook
*
- * It is entrypoint of OAT_FUNCTION_EXECUTE event
+ * OAT_FUNCTION_EXECUTE object ID based event hook entrypoint
*/
void
RunFunctionExecuteHook(Oid objectId)
@@ -143,3 +145,129 @@ RunFunctionExecuteHook(Oid objectId)
ProcedureRelationId, objectId, 0,
NULL);
}
+
+/* String versions */
+
+
+/*
+ * RunObjectPostCreateHookStr
+ *
+ * OAT_POST_CREATE object name based event hook entrypoint
+ */
+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);
+}
+
+/*
+ * RunObjectDropHookStr
+ *
+ * OAT_DROP object name based event hook entrypoint
+ */
+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);
+}
+
+/*
+ * RunObjectTruncateHookStr
+ *
+ * OAT_TRUNCATE object name based event hook entrypoint
+ */
+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);
+}
+
+/*
+ * RunObjectPostAlterHookStr
+ *
+ * OAT_POST_ALTER object name based event hook entrypoint
+ */
+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);
+}
+
+/*
+ * RunNamespaceSearchHookStr
+ *
+ * OAT_NAMESPACE_SEARCH object name based event hook entrypoint
+ */
+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;
+}
+
+/*
+ * RunFunctionExecuteHookStr
+ *
+ * OAT_FUNCTION_EXECUTE object name based event hook entrypoint
+ */
+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 e7f0a380e60..932aefc777d 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -43,6 +43,7 @@
#include "access/xlog_internal.h"
#include "access/xlogrecovery.h"
#include "catalog/namespace.h"
+#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/storage.h"
#include "commands/async.h"
@@ -8737,6 +8738,18 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
}
/*
+ * Invoke the post-alter hook for altering this GUC variable.
+ *
+ * We do this here rather than at the end, because ALTER SYSTEM is not
+ * transactional. If the hook aborts our transaction, it will be cleaner
+ * to do so before we touch any files.
+ */
+ InvokeObjectPostAlterHookArgStr(InvalidOid, name,
+ ACL_ALTER_SYSTEM,
+ altersysstmt->setstmt->kind,
+ false);
+
+ /*
* To ensure crash safety, first write the new file data to a temp file,
* then atomically rename it into place.
*
@@ -8907,6 +8920,10 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
ResetAllOptions();
break;
}
+
+ /* Invoke the post-alter hook for setting this GUC variable. */
+ InvokeObjectPostAlterHookArgStr(InvalidOid, stmt->name,
+ ACL_SET_VALUE, stmt->kind, false);
}
/*
diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h
index 508dfd0a6b3..4d54ae2a7d4 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 */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 6f83a79a96c..2f618cb2292 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -92,7 +92,9 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */
#define ACL_CREATE (1<<9) /* for namespaces and databases */
#define ACL_CREATE_TEMP (1<<10) /* for databases */
#define ACL_CONNECT (1<<11) /* for databases */
-#define N_ACL_RIGHTS 12 /* 1 plus the last 1<<x */
+#define ACL_SET_VALUE (1<<12) /* for configuration parameters */
+#define ACL_ALTER_SYSTEM (1<<13) /* for configuration parameters */
+#define N_ACL_RIGHTS 14 /* 1 plus the last 1<<x */
#define ACL_NO_RIGHTS 0
/* Currently, SELECT ... FOR [KEY] UPDATE/SHARE requires UPDATE privileges */
#define ACL_SELECT_FOR_UPDATE ACL_UPDATE
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 1ce4c5556e7..91ce3d8e9c3 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -146,9 +146,11 @@ typedef struct ArrayType Acl;
#define ACL_CREATE_CHR 'C'
#define ACL_CREATE_TEMP_CHR 'T'
#define ACL_CONNECT_CHR 'c'
+#define ACL_SET_VALUE_CHR 's'
+#define ACL_ALTER_SYSTEM_CHR 'A'
/* string holding all privilege code chars, in order by bitmask position */
-#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTc"
+#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTcsA"
/*
* Bitmasks defining "all rights" for each supported object type