@ -18,7 +18,6 @@
# include "commands/seclabel.h"
# include "executor/executor.h"
# include "fmgr.h"
# include "libpq/auth.h"
# include "miscadmin.h"
# include "tcop/utility.h"
# include "utils/guc.h"
@ -36,10 +35,7 @@ void _PG_init(void);
* Saved hook entries ( if stacked )
*/
static object_access_hook_type next_object_access_hook = NULL ;
static ClientAuthentication_hook_type next_client_auth_hook = NULL ;
static ExecutorCheckPerms_hook_type next_exec_check_perms_hook = NULL ;
static needs_fmgr_hook_type next_needs_fmgr_hook = NULL ;
static fmgr_hook_type next_fmgr_hook = NULL ;
static ProcessUtility_hook_type next_ProcessUtility_hook = NULL ;
static ExecutorStart_hook_type next_ExecutorStart_hook = NULL ;
@ -81,48 +77,6 @@ sepgsql_get_debug_audit(void)
return sepgsql_debug_audit ;
}
/*
* sepgsql_client_auth
*
* Entrypoint of the client authentication hook .
* It switches the client label according to getpeercon ( ) , and the current
* performing mode according to the GUC setting .
*/
static void
sepgsql_client_auth ( Port * port , int status )
{
char * context ;
if ( next_client_auth_hook )
( * next_client_auth_hook ) ( port , status ) ;
/*
* In the case when authentication failed , the supplied socket shall be
* closed soon , so we don ' t need to do anything here .
*/
if ( status ! = STATUS_OK )
return ;
/*
* Getting security label of the peer process using API of libselinux .
*/
if ( getpeercon_raw ( port - > sock , & context ) < 0 )
ereport ( FATAL ,
( errcode ( ERRCODE_INTERNAL_ERROR ) ,
errmsg ( " SELinux: unable to get peer label: %m " ) ) ) ;
sepgsql_set_client_label ( context ) ;
/*
* Switch the current performing mode from INTERNAL to either DEFAULT or
* PERMISSIVE .
*/
if ( sepgsql_permissive )
sepgsql_set_mode ( SEPGSQL_MODE_PERMISSIVE ) ;
else
sepgsql_set_mode ( SEPGSQL_MODE_DEFAULT ) ;
}
/*
* sepgsql_object_access
*
@ -220,121 +174,6 @@ sepgsql_exec_check_perms(List *rangeTabls, bool abort)
return true ;
}
/*
* sepgsql_needs_fmgr_hook
*
* It informs the core whether the supplied function is trusted procedure ,
* or not . If true , sepgsql_fmgr_hook shall be invoked at start , end , and
* abort time of function invocation .
*/
static bool
sepgsql_needs_fmgr_hook ( Oid functionId )
{
ObjectAddress object ;
if ( next_needs_fmgr_hook & &
( * next_needs_fmgr_hook ) ( functionId ) )
return true ;
/*
* SELinux needs the function to be called via security_definer wrapper ,
* if this invocation will take a domain - transition . We call these
* functions as trusted - procedure , if the security policy has a rule that
* switches security label of the client on execution .
*/
if ( sepgsql_avc_trusted_proc ( functionId ) ! = NULL )
return true ;
/*
* Even if not a trusted - procedure , this function should not be inlined
* unless the client has db_procedure : { execute } permission . Please note
* that it shall be actually failed later because of same reason with
* ACL_EXECUTE .
*/
object . classId = ProcedureRelationId ;
object . objectId = functionId ;
object . objectSubId = 0 ;
if ( ! sepgsql_avc_check_perms ( & object ,
SEPG_CLASS_DB_PROCEDURE ,
SEPG_DB_PROCEDURE__EXECUTE ,
SEPGSQL_AVC_NOAUDIT , false ) )
return true ;
return false ;
}
/*
* sepgsql_fmgr_hook
*
* It switches security label of the client on execution of trusted
* procedures .
*/
static void
sepgsql_fmgr_hook ( FmgrHookEventType event ,
FmgrInfo * flinfo , Datum * private )
{
struct
{
char * old_label ;
char * new_label ;
Datum next_private ;
} * stack ;
switch ( event )
{
case FHET_START :
stack = ( void * ) DatumGetPointer ( * private ) ;
if ( ! stack )
{
MemoryContext oldcxt ;
oldcxt = MemoryContextSwitchTo ( flinfo - > fn_mcxt ) ;
stack = palloc ( sizeof ( * stack ) ) ;
stack - > old_label = NULL ;
stack - > new_label = sepgsql_avc_trusted_proc ( flinfo - > fn_oid ) ;
stack - > next_private = 0 ;
MemoryContextSwitchTo ( oldcxt ) ;
/*
* process : transition permission between old and new label ,
* when user tries to switch security label of the client
* on execution of trusted procedure .
*/
if ( stack - > new_label )
sepgsql_avc_check_perms_label ( stack - > new_label ,
SEPG_CLASS_PROCESS ,
SEPG_PROCESS__TRANSITION ,
NULL , true ) ;
* private = PointerGetDatum ( stack ) ;
}
Assert ( ! stack - > old_label ) ;
if ( stack - > new_label )
stack - > old_label = sepgsql_set_client_label ( stack - > new_label ) ;
if ( next_fmgr_hook )
( * next_fmgr_hook ) ( event , flinfo , & stack - > next_private ) ;
break ;
case FHET_END :
case FHET_ABORT :
stack = ( void * ) DatumGetPointer ( * private ) ;
if ( next_fmgr_hook )
( * next_fmgr_hook ) ( event , flinfo , & stack - > next_private ) ;
if ( stack - > old_label )
sepgsql_set_client_label ( stack - > old_label ) ;
stack - > old_label = NULL ;
break ;
default :
elog ( ERROR , " unexpected event type: %d " , ( int ) event ) ;
break ;
}
}
/*
* sepgsql_executor_start
*
@ -465,8 +304,6 @@ sepgsql_utility_command(Node *parsetree,
void
_PG_init ( void )
{
char * context ;
/*
* We allow to load the SE - PostgreSQL module on single - user - mode or
* shared_preload_libraries settings only .
@ -522,33 +359,16 @@ _PG_init(void)
NULL ,
NULL ) ;
/*
* Set up dummy client label .
*
* XXX - note that PostgreSQL launches background worker process like
* autovacuum without authentication steps . So , we initialize sepgsql_mode
* with SEPGSQL_MODE_INTERNAL , and client_label with the security context
* of server process . Later , it also launches background of user session .
* In this case , the process is always hooked on post - authentication , and
* we can initialize the sepgsql_mode and client_label correctly .
*/
if ( getcon_raw ( & context ) < 0 )
ereport ( ERROR ,
( errcode ( ERRCODE_INTERNAL_ERROR ) ,
errmsg ( " SELinux: failed to get server security label: %m " ) ) ) ;
sepgsql_set_client_label ( context ) ;
/* Initialize userspace access vector cache */
sepgsql_avc_init ( ) ;
/* Initialize security label of the client and related stuff */
sepgsql_init_client_label ( ) ;
/* Security label provider hook */
register_label_provider ( SEPGSQL_LABEL_TAG ,
sepgsql_object_relabel ) ;
/* Client authentication hook */
next_client_auth_hook = ClientAuthentication_hook ;
ClientAuthentication_hook = sepgsql_client_auth ;
/* Object access hook */
next_object_access_hook = object_access_hook ;
object_access_hook = sepgsql_object_access ;
@ -557,13 +377,6 @@ _PG_init(void)
next_exec_check_perms_hook = ExecutorCheckPerms_hook ;
ExecutorCheckPerms_hook = sepgsql_exec_check_perms ;
/* Trusted procedure hooks */
next_needs_fmgr_hook = needs_fmgr_hook ;
needs_fmgr_hook = sepgsql_needs_fmgr_hook ;
next_fmgr_hook = fmgr_hook ;
fmgr_hook = sepgsql_fmgr_hook ;
/* ProcessUtility hook */
next_ProcessUtility_hook = ProcessUtility_hook ;
ProcessUtility_hook = sepgsql_utility_command ;