aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/objectaccess.c17
-rw-r--r--src/backend/executor/execQual.c3
-rw-r--r--src/backend/executor/nodeAgg.c4
-rw-r--r--src/backend/executor/nodeWindowAgg.c4
-rw-r--r--src/backend/tcop/fastpath.c1
-rw-r--r--src/include/catalog/objectaccess.h14
6 files changed, 43 insertions, 0 deletions
diff --git a/src/backend/catalog/objectaccess.c b/src/backend/catalog/objectaccess.c
index ad12d74f521..87158e34e26 100644
--- a/src/backend/catalog/objectaccess.c
+++ b/src/backend/catalog/objectaccess.c
@@ -12,6 +12,7 @@
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace.h"
+#include "catalog/pg_proc.h"
/*
* Hook on object accesses. This is intended as infrastructure for security
@@ -109,3 +110,19 @@ RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
return ns_arg.result;
}
+
+/*
+ * RunFunctionExecuteHook
+ *
+ * It is entrypoint of OAT_FUNCTION_EXECUTE event
+ */
+void
+RunFunctionExecuteHook(Oid objectId)
+{
+ /* caller should check, but just in case... */
+ Assert(object_access_hook != NULL);
+
+ (*object_access_hook)(OAT_FUNCTION_EXECUTE,
+ ProcedureRelationId, objectId, 0,
+ NULL);
+}
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 62d27a75747..330d889eba9 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -39,6 +39,7 @@
#include "access/htup_details.h"
#include "access/nbtree.h"
#include "access/tupconvert.h"
+#include "catalog/objectaccess.h"
#include "catalog/pg_type.h"
#include "commands/typecmds.h"
#include "executor/execdebug.h"
@@ -1289,6 +1290,7 @@ init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(foid));
+ InvokeFunctionExecuteHook(foid);
/*
* Safety check on nargs. Under normal circumstances this should never
@@ -4223,6 +4225,7 @@ ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(acoerce->elemfuncid));
+ InvokeFunctionExecuteHook(acoerce->elemfuncid);
/* Set up the primary fmgr lookup information */
fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 7efc4905cf4..c741131b257 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -79,6 +79,7 @@
#include "postgres.h"
#include "access/htup_details.h"
+#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
@@ -1625,6 +1626,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(aggref->aggfnoid));
+ InvokeFunctionExecuteHook(aggref->aggfnoid);
peraggstate->transfn_oid = transfn_oid = aggform->aggtransfn;
peraggstate->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
@@ -1647,6 +1649,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(transfn_oid));
+ InvokeFunctionExecuteHook(transfn_oid);
if (OidIsValid(finalfn_oid))
{
aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
@@ -1654,6 +1657,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(finalfn_oid));
+ InvokeFunctionExecuteHook(finalfn_oid);
}
}
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3bc42baed10..d9f0e79d10c 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -34,6 +34,7 @@
#include "postgres.h"
#include "access/htup_details.h"
+#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
@@ -1559,6 +1560,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(wfunc->winfnoid));
+ InvokeFunctionExecuteHook(wfunc->winfnoid);
/* Fill in the perfuncstate data */
perfuncstate->wfuncstate = wfuncstate;
@@ -1767,6 +1769,7 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc,
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(transfn_oid));
+ InvokeFunctionExecuteHook(transfn_oid);
if (OidIsValid(finalfn_oid))
{
aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
@@ -1774,6 +1777,7 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc,
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(finalfn_oid));
+ InvokeFunctionExecuteHook(finalfn_oid);
}
}
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index 016e7d9ec66..bd0801c0bf7 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -362,6 +362,7 @@ HandleFunctionRequest(StringInfo msgBuf)
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_PROC,
get_func_name(fid));
+ InvokeFunctionExecuteHook(fid);
/*
* Prepare function call info block and insert arguments.
diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h
index a34c4c7474b..f4e464e566b 100644
--- a/src/include/catalog/objectaccess.h
+++ b/src/include/catalog/objectaccess.h
@@ -31,6 +31,12 @@
* a particular namespace. This event is equivalent to usage permission
* on a schema under the default access control mechanism.
*
+ * OAT_FUNCTION_EXECUTE should be invoked prior to function execution.
+ * This event is almost equivalent to execute permission on functions,
+ * except for the case when execute permission is checked during object
+ * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are
+ * sufficient for extensions to track these kind of checks.
+ *
* Other types may be added in the future.
*/
typedef enum ObjectAccessType
@@ -39,6 +45,7 @@ typedef enum ObjectAccessType
OAT_DROP,
OAT_POST_ALTER,
OAT_NAMESPACE_SEARCH,
+ OAT_FUNCTION_EXECUTE,
} ObjectAccessType;
/*
@@ -129,6 +136,7 @@ extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,
extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
Oid auxiliaryId, bool is_internal);
extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_volation);
+extern void RunFunctionExecuteHook(Oid objectId);
/*
* The following macros are wrappers around the functions above; these should
@@ -170,4 +178,10 @@ extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_volation);
? true \
: RunNamespaceSearchHook((objectId), (ereport_on_violation)))
+#define InvokeFunctionExecuteHook(objectId) \
+ do { \
+ if (object_access_hook) \
+ RunFunctionExecuteHook(objectId); \
+ } while(0)
+
#endif /* OBJECTACCESS_H */