Skip to content

Commit

Permalink
Babelfish support cross database function/procedure execution (#434)
Browse files Browse the repository at this point in the history
Support cross database function or procedure execution ie, call a function in one database
from another database. Here we are talking about Babelfish logical database
which is different from a physical Postgres database.
To support this, introduced a hook in `ExecFuncProc_AclCheck_hook` to perform permission check
to execute specified function/procedure. This hook will decide whether to use current_user
(user of current T-SQL database) or session user (login) depending upon if the
function is from a different database or not. The reason login can be used for permission
check is since login is member of all it’s users, so it inherits all their permissions so it
will be able execute any cross database function/procedure owned by its users.
Additionally, introduce `SYSNAMESPACENAME` syscache entry for
sys.babelfish_namespace_ext catalog so that schema look-ups in this catalog becomes
fast.

Task: BABEL-5206
Signed-off-by: Rishabh Tanwar <[email protected]> 

Extension PR: babelfish-for-postgresql/babelfish_extensions#2899
  • Loading branch information
rishabhtanwar29 authored Sep 20, 2024
1 parent e57f03a commit ae1fa4d
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/backend/commands/functioncmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "commands/proclang.h"
#include "commands/trigger.h"
#include "commands/tablecmds.h"
#include "executor/execExpr.h"
#include "executor/execdesc.h"
#include "executor/executor.h"
#include "executor/functions.h"
Expand Down Expand Up @@ -2349,7 +2350,10 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
Assert(fexpr);
Assert(IsA(fexpr, FuncExpr));

aclresult = object_aclcheck(ProcedureRelationId, fexpr->funcid, GetUserId(), ACL_EXECUTE);
if (ExecFuncProc_AclCheck_hook)
aclresult = ExecFuncProc_AclCheck_hook(fexpr->funcid);
else
aclresult = object_aclcheck(ProcedureRelationId, fexpr->funcid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_PROCEDURE, get_func_name(fexpr->funcid));

Expand Down
7 changes: 6 additions & 1 deletion src/backend/executor/execExpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ typedef struct ExprSetupInfo
List *multiexpr_subplans;
} ExprSetupInfo;

ExecFuncProc_AclCheck_hook_type ExecFuncProc_AclCheck_hook = NULL;

static void ExecReadyExpr(ExprState *state);
static void ExecInitExprRec(Expr *node, ExprState *state,
Datum *resv, bool *resnull);
Expand Down Expand Up @@ -2557,7 +2559,10 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
ListCell *lc;

/* Check permission to call function */
aclresult = object_aclcheck(ProcedureRelationId, funcid, GetUserId(), ACL_EXECUTE);
if (ExecFuncProc_AclCheck_hook)
aclresult = ExecFuncProc_AclCheck_hook(funcid);
else
aclresult = object_aclcheck(ProcedureRelationId, funcid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(funcid));
InvokeFunctionExecuteHook(funcid);
Expand Down
9 changes: 9 additions & 0 deletions src/include/executor/execExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "executor/nodeAgg.h"
#include "nodes/execnodes.h"
#include "utils/acl.h"

/* forward references to avoid circularity */
struct ExprEvalStep;
Expand All @@ -39,6 +40,14 @@ typedef bool (*ExecEvalBoolSubroutine) (ExprState *state,
struct ExprEvalStep *op,
ExprContext *econtext);

/*
* Hook to perform permission check to EXECUTE a function or procedure.
* Helpful in cases when permissions need to be checked against
* a different user instead of current user.
*/
typedef AclResult (*ExecFuncProc_AclCheck_hook_type) (Oid funcid);
extern PGDLLIMPORT ExecFuncProc_AclCheck_hook_type ExecFuncProc_AclCheck_hook;

/* ExprEvalSteps that cache a composite type's tupdesc need one of these */
/* (it fits in-line in some step types, otherwise allocate out-of-line) */
typedef struct ExprEvalRowtypeCache
Expand Down
6 changes: 4 additions & 2 deletions src/include/utils/syscache.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,12 @@ enum SysCacheIdentifier
*/
SYSDATABASEOID,
SYSDATABASENAME,
PROCNAMENSPSIGNATURE
PROCNAMENSPSIGNATURE,
SYSNAMESPACENAME,
AUTHIDUSEREXTROLENAME

#define SysCacheNoExtensionSize (USERMAPPINGUSERSERVER+ 1)
#define SysCacheSize (PROCNAMENSPSIGNATURE + 1)
#define SysCacheSize (AUTHIDUSEREXTROLENAME + 1)
};

/*
Expand Down

0 comments on commit ae1fa4d

Please sign in to comment.