2005-10-07 18:07:38 +04:00
/* permission.c: key permission determination
*
* Copyright ( C ) 2005 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# include <linux/module.h>
2005-10-31 02:02:44 +03:00
# include <linux/security.h>
2005-10-07 18:07:38 +04:00
# include "internal.h"
/*****************************************************************************/
/*
* check to see whether permission is granted to use a key in the desired way ,
* but permit the security modules to override
*/
int key_task_permission ( const key_ref_t key_ref ,
struct task_struct * context ,
key_perm_t perm )
{
2008-11-14 02:39:19 +03:00
const struct cred * cred ;
2005-10-07 18:07:38 +04:00
struct key * key ;
key_perm_t kperm ;
int ret ;
key = key_ref_to_ptr ( key_ref ) ;
2008-11-14 02:39:19 +03:00
rcu_read_lock ( ) ;
cred = __task_cred ( context ) ;
2005-10-07 18:07:38 +04:00
/* use the second 8-bits of permissions for keys the caller owns */
2008-11-14 02:39:16 +03:00
if ( key - > uid = = cred - > fsuid ) {
2005-10-07 18:07:38 +04:00
kperm = key - > perm > > 16 ;
goto use_these_perms ;
}
/* use the third 8-bits of permissions for keys the caller has a group
* membership in common with */
if ( key - > gid ! = - 1 & & key - > perm & KEY_GRP_ALL ) {
2008-11-14 02:39:16 +03:00
if ( key - > gid = = cred - > fsgid ) {
2005-10-07 18:07:38 +04:00
kperm = key - > perm > > 8 ;
goto use_these_perms ;
}
2008-11-14 02:39:16 +03:00
ret = groups_search ( cred - > group_info , key - > gid ) ;
2005-10-07 18:07:38 +04:00
if ( ret ) {
kperm = key - > perm > > 8 ;
goto use_these_perms ;
}
}
/* otherwise use the least-significant 8-bits */
kperm = key - > perm ;
use_these_perms :
2008-11-14 02:39:19 +03:00
rcu_read_lock ( ) ;
2005-10-07 19:41:24 +04:00
/* use the top 8-bits of permissions for keys the caller possesses
* - possessor permissions are additive with other permissions
*/
if ( is_key_possessed ( key_ref ) )
kperm | = key - > perm > > 24 ;
2005-10-07 18:07:38 +04:00
kperm = kperm & perm & KEY_ALL ;
2005-10-31 02:02:44 +03:00
if ( kperm ! = perm )
return - EACCES ;
/* let LSM be the final arbiter */
return security_key_permission ( key_ref , context , perm ) ;
2005-10-07 18:07:38 +04:00
} /* end key_task_permission() */
EXPORT_SYMBOL ( key_task_permission ) ;
2006-01-08 12:02:47 +03:00
/*****************************************************************************/
/*
* validate a key
*/
int key_validate ( struct key * key )
{
struct timespec now ;
int ret = 0 ;
if ( key ) {
/* check it's still accessible */
ret = - EKEYREVOKED ;
if ( test_bit ( KEY_FLAG_REVOKED , & key - > flags ) | |
test_bit ( KEY_FLAG_DEAD , & key - > flags ) )
goto error ;
/* check it hasn't expired */
ret = 0 ;
if ( key - > expiry ) {
now = current_kernel_time ( ) ;
if ( now . tv_sec > = key - > expiry )
ret = - EKEYEXPIRED ;
}
}
error :
return ret ;
} /* end key_validate() */
EXPORT_SYMBOL ( key_validate ) ;