@ -2,7 +2,11 @@
*
*
* superuser . c
* superuser . c
* The superuser ( ) function . Determines if user has superuser privilege .
* The superuser ( ) function . Determines if user has superuser privilege .
* Also , a function to check for the owner ( datdba ) of a database .
*
* All code should use either of these two functions to find out
* whether a given user is a superuser , rather than examining
* pg_shadow . usesuper directly , so that the escape hatch built in for
* the single - user case works .
*
*
*
*
* Portions Copyright ( c ) 1996 - 2005 , PostgreSQL Global Development Group
* Portions Copyright ( c ) 1996 - 2005 , PostgreSQL Global Development Group
@ -10,26 +14,33 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / utils / misc / superuser . c , v 1.30 2004 / 12 / 31 22 : 02 : 45 pgsq l Exp $
* $ PostgreSQL : pgsql / src / backend / utils / misc / superuser . c , v 1.31 2005 / 05 / 29 20 : 38 : 06 tg l Exp $
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
# include "postgres.h"
# include "postgres.h"
# include "access/heapam.h"
# include "catalog/pg_shadow.h"
# include "catalog/pg_shadow.h"
# include "commands/dbcommands .h"
# include "utils/inval .h"
# include "utils/syscache.h"
# include "utils/syscache.h"
# include "miscadmin.h"
# include "miscadmin.h"
/*
* In common cases the same userid ( ie , the session or current ID ) will
* be queried repeatedly . So we maintain a simple one - entry cache for
* the status of the last requested userid . The cache can be flushed
* at need by watching for cache update events on pg_shadow .
*/
static AclId last_userid = 0 ; /* 0 == cache not valid */
static bool last_userid_is_super = false ;
static bool userid_callback_registered = false ;
static void UseridCallback ( Datum arg , Oid relid ) ;
/*
/*
* The Postgres user running this command has Postgres superuser privileges
* The Postgres user running this command has Postgres superuser privileges
*
* All code should use either of these two functions to find out
* whether a given user is a superuser , rather than evaluating
* pg_shadow . usesuper directly , so that the escape hatch built in for
* the single - user case works .
*/
*/
bool
bool
superuser ( void )
superuser ( void )
@ -38,16 +49,24 @@ superuser(void)
}
}
/*
* The specified userid has Postgres superuser privileges
*/
bool
bool
superuser_arg ( AclId userid )
superuser_arg ( AclId userid )
{
{
bool result = false ;
bool result ;
HeapTuple utup ;
HeapTuple utup ;
/* Quick out for cache hit */
if ( AclIdIsValid ( last_userid ) & & last_userid = = userid )
return last_userid_is_super ;
/* Special escape path in case you deleted all your users. */
/* Special escape path in case you deleted all your users. */
if ( ! IsUnderPostmaster & & userid = = BOOTSTRAP_USESYSID )
if ( ! IsUnderPostmaster & & userid = = BOOTSTRAP_USESYSID )
return true ;
return true ;
/* OK, look up the information in pg_shadow */
utup = SearchSysCache ( SHADOWSYSID ,
utup = SearchSysCache ( SHADOWSYSID ,
Int32GetDatum ( userid ) ,
Int32GetDatum ( userid ) ,
0 , 0 , 0 ) ;
0 , 0 , 0 ) ;
@ -56,5 +75,35 @@ superuser_arg(AclId userid)
result = ( ( Form_pg_shadow ) GETSTRUCT ( utup ) ) - > usesuper ;
result = ( ( Form_pg_shadow ) GETSTRUCT ( utup ) ) - > usesuper ;
ReleaseSysCache ( utup ) ;
ReleaseSysCache ( utup ) ;
}
}
else
{
/* Report "not superuser" for invalid userids */
result = false ;
}
/* If first time through, set up callback for cache flushes */
if ( ! userid_callback_registered )
{
CacheRegisterSyscacheCallback ( SHADOWSYSID ,
UseridCallback ,
( Datum ) 0 ) ;
userid_callback_registered = true ;
}
/* Cache the result for next time */
last_userid = userid ;
last_userid_is_super = result ;
return result ;
return result ;
}
}
/*
* UseridCallback
* Syscache inval callback function
*/
static void
UseridCallback ( Datum arg , Oid relid )
{
/* Invalidate our local cache in case user's superuserness changed */
last_userid = 0 ;
}