@ -612,7 +612,8 @@ struct fmgr_security_definer_cache
{
{
FmgrInfo flinfo ; /* lookup info for target function */
FmgrInfo flinfo ; /* lookup info for target function */
Oid userid ; /* userid to set, or InvalidOid */
Oid userid ; /* userid to set, or InvalidOid */
ArrayType * proconfig ; /* GUC values to set, or NULL */
List * configNames ; /* GUC names to set, or NIL */
List * configValues ; /* GUC values to set, or NIL */
Datum arg ; /* passthrough argument for plugin modules */
Datum arg ; /* passthrough argument for plugin modules */
} ;
} ;
@ -634,6 +635,8 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
FmgrInfo * save_flinfo ;
FmgrInfo * save_flinfo ;
Oid save_userid ;
Oid save_userid ;
int save_sec_context ;
int save_sec_context ;
ListCell * lc1 ;
ListCell * lc2 ;
volatile int save_nestlevel ;
volatile int save_nestlevel ;
PgStat_FunctionCallUsage fcusage ;
PgStat_FunctionCallUsage fcusage ;
@ -666,8 +669,11 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
& isnull ) ;
& isnull ) ;
if ( ! isnull )
if ( ! isnull )
{
{
ArrayType * array ;
oldcxt = MemoryContextSwitchTo ( fcinfo - > flinfo - > fn_mcxt ) ;
oldcxt = MemoryContextSwitchTo ( fcinfo - > flinfo - > fn_mcxt ) ;
fcache - > proconfig = DatumGetArrayTypePCopy ( datum ) ;
array = DatumGetArrayTypeP ( datum ) ;
TransformGUCArray ( array , & fcache - > configNames ,
& fcache - > configValues ) ;
MemoryContextSwitchTo ( oldcxt ) ;
MemoryContextSwitchTo ( oldcxt ) ;
}
}
@ -680,7 +686,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
/* GetUserIdAndSecContext is cheap enough that no harm in a wasted call */
/* GetUserIdAndSecContext is cheap enough that no harm in a wasted call */
GetUserIdAndSecContext ( & save_userid , & save_sec_context ) ;
GetUserIdAndSecContext ( & save_userid , & save_sec_context ) ;
if ( fcache - > pro config) /* Need a new GUC nesting level */
if ( fcache - > configNames ! = NIL ) /* Need a new GUC nesting level */
save_nestlevel = NewGUCNestLevel ( ) ;
save_nestlevel = NewGUCNestLevel ( ) ;
else
else
save_nestlevel = 0 ; /* keep compiler quiet */
save_nestlevel = 0 ; /* keep compiler quiet */
@ -689,12 +695,17 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
SetUserIdAndSecContext ( fcache - > userid ,
SetUserIdAndSecContext ( fcache - > userid ,
save_sec_context | SECURITY_LOCAL_USERID_CHANGE ) ;
save_sec_context | SECURITY_LOCAL_USERID_CHANGE ) ;
if ( fcache - > proconfig )
forboth ( lc1 , fcache - > configNames , lc2 , fcache - > configValues )
{
{
ProcessGUCArray ( fcache - > proconfig ,
GucContext context = superuser ( ) ? PGC_SUSET : PGC_USERSET ;
( superuser ( ) ? PGC_SUSET : PGC_USERSET ) ,
GucSource source = PGC_S_SESSION ;
PGC_S_SESSION ,
GucAction action = GUC_ACTION_SAVE ;
GUC_ACTION_SAVE ) ;
char * name = lfirst ( lc1 ) ;
char * value = lfirst ( lc2 ) ;
( void ) set_config_option ( name , value ,
context , source ,
action , true , 0 , false ) ;
}
}
/* function manager hook */
/* function manager hook */
@ -737,7 +748,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
fcinfo - > flinfo = save_flinfo ;
fcinfo - > flinfo = save_flinfo ;
if ( fcache - > pro config)
if ( fcache - > configNames ! = NIL )
AtEOXact_GUC ( true , save_nestlevel ) ;
AtEOXact_GUC ( true , save_nestlevel ) ;
if ( OidIsValid ( fcache - > userid ) )
if ( OidIsValid ( fcache - > userid ) )
SetUserIdAndSecContext ( save_userid , save_sec_context ) ;
SetUserIdAndSecContext ( save_userid , save_sec_context ) ;