@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / utils / init / miscinit . c , v 1.175 2009 / 06 / 11 14 : 49 : 05 momjian Exp $
* $ PostgreSQL : pgsql / src / backend / utils / init / miscinit . c , v 1.175 .2 .1 2009 / 12 / 09 21 : 58 : 04 tgl Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -272,8 +272,10 @@ make_absolute_path(const char *path)
* be the same as OuterUserId , but it changes during calls to SECURITY
* DEFINER functions , as well as locally in some specialized commands .
*
* SecurityDefinerContext is TRUE if we are within a SECURITY DEFINER function
* or another context that temporarily changes CurrentUserId .
* SecurityRestrictionContext holds flags indicating reason ( s ) for changing
* CurrentUserId . In some cases we need to lock down operations that are
* not directly controlled by privilege settings , and this provides a
* convenient way to do it .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
static Oid AuthenticatedUserId = InvalidOid ;
@ -285,7 +287,7 @@ static Oid CurrentUserId = InvalidOid;
static bool AuthenticatedUserIsSuperuser = false ;
static bool SessionUserIsSuperuser = false ;
static bool SecurityDefinerContext = false ;
static int SecurityRestrictionContext = 0 ;
/* We also remember if a SET ROLE is currently active */
static bool SetRoleIsActive = false ;
@ -294,7 +296,7 @@ static bool SetRoleIsActive = false;
/*
* GetUserId - get the current effective user ID .
*
* Note : there ' s no SetUserId ( ) anymore ; use SetUserIdAndContext ( ) .
* Note : there ' s no SetUserId ( ) anymore ; use SetUserIdAndSec Context ( ) .
*/
Oid
GetUserId ( void )
@ -318,7 +320,7 @@ GetOuterUserId(void)
static void
SetOuterUserId ( Oid userid )
{
AssertState ( ! SecurityDefinerContext ) ;
AssertState ( SecurityRestrictionContext = = 0 ) ;
AssertArg ( OidIsValid ( userid ) ) ;
OuterUserId = userid ;
@ -341,7 +343,7 @@ GetSessionUserId(void)
static void
SetSessionUserId ( Oid userid , bool is_superuser )
{
AssertState ( ! SecurityDefinerContext ) ;
AssertState ( SecurityRestrictionContext = = 0 ) ;
AssertArg ( OidIsValid ( userid ) ) ;
SessionUserId = userid ;
SessionUserIsSuperuser = is_superuser ;
@ -354,11 +356,29 @@ SetSessionUserId(Oid userid, bool is_superuser)
/*
* GetUserIdAndContext / SetUserIdAndContext - get / set the current user ID
* and the SecurityDefinerContext flag .
* GetUserIdAndSec Context / SetUserIdAndSec Context - get / set the current user ID
* and the SecurityRestrictionContext flags .
*
* Unlike GetUserId , GetUserIdAndContext does * not * Assert that the current
* value of CurrentUserId is valid ; nor does SetUserIdAndContext require
* Currently there are two valid bits in SecurityRestrictionContext :
*
* SECURITY_LOCAL_USERID_CHANGE indicates that we are inside an operation
* that is temporarily changing CurrentUserId via these functions . This is
* needed to indicate that the actual value of CurrentUserId is not in sync
* with guc . c ' s internal state , so SET ROLE has to be disallowed .
*
* SECURITY_RESTRICTED_OPERATION indicates that we are inside an operation
* that does not wish to trust called user - defined functions at all . This
* bit prevents not only SET ROLE , but various other changes of session state
* that normally is unprotected but might possibly be used to subvert the
* calling session later . An example is replacing an existing prepared
* statement with new code , which will then be executed with the outer
* session ' s permissions when the prepared statement is next used . Since
* these restrictions are fairly draconian , we apply them only in contexts
* where the called functions are really supposed to be side - effect - free
* anyway , such as VACUUM / ANALYZE / REINDEX .
*
* Unlike GetUserId , GetUserIdAndSecContext does * not * Assert that the current
* value of CurrentUserId is valid ; nor does SetUserIdAndSecContext require
* the new value to be valid . In fact , these routines had better not
* ever throw any kind of error . This is because they are used by
* StartTransaction and AbortTransaction to save / restore the settings ,
@ -367,27 +387,66 @@ SetSessionUserId(Oid userid, bool is_superuser)
* through AbortTransaction without asserting in case InitPostgres fails .
*/
void
GetUserIdAndContext ( Oid * userid , bool * sec_def _context )
GetUserIdAndSec Context ( Oid * userid , int * sec_context )
{
* userid = CurrentUserId ;
* sec_def_ context = SecurityDefiner Context ;
* sec_context = SecurityRestriction Context ;
}
void
SetUserIdAndContext ( Oid userid , bool sec_def _context)
SetUserIdAndSec Context ( Oid userid , int sec _context)
{
CurrentUserId = userid ;
SecurityDefiner Context = sec_def _context ;
SecurityRestriction Context = sec_context ;
}
/*
* InSecurityDefinerContext - are we inside a SECURITY DEFINER context ?
* InLocalUserIdChange - are we inside a local change of CurrentUserId ?
*/
bool
InSecurityDefinerContext ( void )
InLocalUserIdChange ( void )
{
return SecurityDefinerContext ;
return ( SecurityRestrictionContext & SECURITY_LOCAL_USERID_CHANGE ) ! = 0 ;
}
/*
* InSecurityRestrictedOperation - are we inside a security - restricted command ?
*/
bool
InSecurityRestrictedOperation ( void )
{
return ( SecurityRestrictionContext & SECURITY_RESTRICTED_OPERATION ) ! = 0 ;
}
/*
* These are obsolete versions of Get / SetUserIdAndSecContext that are
* only provided for bug - compatibility with some rather dubious code in
* pljava . We allow the userid to be set , but only when not inside a
* security restriction context .
*/
void
GetUserIdAndContext ( Oid * userid , bool * sec_def_context )
{
* userid = CurrentUserId ;
* sec_def_context = InLocalUserIdChange ( ) ;
}
void
SetUserIdAndContext ( Oid userid , bool sec_def_context )
{
/* We throw the same error SET ROLE would. */
if ( InSecurityRestrictedOperation ( ) )
ereport ( ERROR ,
( errcode ( ERRCODE_INSUFFICIENT_PRIVILEGE ) ,
errmsg ( " cannot set parameter \" %s \" within security-restricted operation " ,
" role " ) ) ) ;
CurrentUserId = userid ;
if ( sec_def_context )
SecurityRestrictionContext | = SECURITY_LOCAL_USERID_CHANGE ;
else
SecurityRestrictionContext & = ~ SECURITY_LOCAL_USERID_CHANGE ;
}