diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/catalog/objectaccess.c | 17 | ||||
-rw-r--r-- | src/backend/executor/execQual.c | 3 | ||||
-rw-r--r-- | src/backend/executor/nodeAgg.c | 4 | ||||
-rw-r--r-- | src/backend/executor/nodeWindowAgg.c | 4 | ||||
-rw-r--r-- | src/backend/tcop/fastpath.c | 1 | ||||
-rw-r--r-- | src/include/catalog/objectaccess.h | 14 |
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 */ |