2005-04-17 02:20:36 +04:00
/* keyctl.c: userspace keyctl operations
*
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
* Copyright ( C ) 2004 - 5 Red Hat , Inc . All Rights Reserved .
2005-04-17 02:20:36 +04:00
* 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>
# include <linux/init.h>
# include <linux/sched.h>
# include <linux/slab.h>
# include <linux/syscalls.h>
# include <linux/keyctl.h>
# include <linux/fs.h>
2006-01-11 23:17:46 +03:00
# include <linux/capability.h>
2006-03-24 14:18:43 +03:00
# include <linux/string.h>
2005-04-17 02:20:36 +04:00
# include <linux/err.h>
2008-04-29 12:01:19 +04:00
# include <linux/vmalloc.h>
2008-04-29 12:01:26 +04:00
# include <linux/security.h>
2005-04-17 02:20:36 +04:00
# include <asm/uaccess.h>
# include "internal.h"
2006-03-24 14:18:43 +03:00
static int key_get_type_from_user ( char * type ,
const char __user * _type ,
unsigned len )
{
int ret ;
ret = strncpy_from_user ( type , _type , len ) ;
if ( ret < 0 )
return - EFAULT ;
if ( ret = = 0 | | ret > = len )
return - EINVAL ;
if ( type [ 0 ] = = ' . ' )
return - EPERM ;
type [ len - 1 ] = ' \0 ' ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
/*****************************************************************************/
/*
* extract the description of a new key from userspace and either add it as a
* new key to the specified keyring or update a matching key in that keyring
* - the keyring must be writable
* - returns the new key ' s serial number
* - implements add_key ( )
*/
asmlinkage long sys_add_key ( const char __user * _type ,
const char __user * _description ,
const void __user * _payload ,
size_t plen ,
key_serial_t ringid )
{
2005-09-28 20:03:15 +04:00
key_ref_t keyring_ref , key_ref ;
2005-04-17 02:20:36 +04:00
char type [ 32 ] , * description ;
void * payload ;
2006-03-24 14:18:43 +03:00
long ret ;
2008-04-29 12:01:19 +04:00
bool vm ;
2005-04-17 02:20:36 +04:00
ret = - EINVAL ;
2008-04-29 12:01:19 +04:00
if ( plen > 1024 * 1024 - 1 )
2005-04-17 02:20:36 +04:00
goto error ;
/* draw all the data into kernel space */
2006-03-24 14:18:43 +03:00
ret = key_get_type_from_user ( type , _type , sizeof ( type ) ) ;
2005-04-17 02:20:36 +04:00
if ( ret < 0 )
goto error ;
2006-03-24 14:18:43 +03:00
description = strndup_user ( _description , PAGE_SIZE ) ;
if ( IS_ERR ( description ) ) {
ret = PTR_ERR ( description ) ;
2005-04-17 02:20:36 +04:00
goto error ;
2006-03-24 14:18:43 +03:00
}
2005-04-17 02:20:36 +04:00
/* pull the payload in if one was supplied */
payload = NULL ;
2008-04-29 12:01:19 +04:00
vm = false ;
2005-04-17 02:20:36 +04:00
if ( _payload ) {
ret = - ENOMEM ;
payload = kmalloc ( plen , GFP_KERNEL ) ;
2008-04-29 12:01:19 +04:00
if ( ! payload ) {
if ( plen < = PAGE_SIZE )
goto error2 ;
vm = true ;
payload = vmalloc ( plen ) ;
if ( ! payload )
goto error2 ;
}
2005-04-17 02:20:36 +04:00
ret = - EFAULT ;
if ( copy_from_user ( payload , _payload , plen ) ! = 0 )
goto error3 ;
}
/* find the target keyring (which must be writable) */
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
keyring_ref = lookup_user_key ( ringid , 1 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( keyring_ref ) ) {
ret = PTR_ERR ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
goto error3 ;
}
/* create or update the requested key and add it to the target
* keyring */
2005-09-28 20:03:15 +04:00
key_ref = key_create_or_update ( keyring_ref , type , description ,
2008-04-29 12:01:28 +04:00
payload , plen , KEY_PERM_UNDEF ,
KEY_ALLOC_IN_QUOTA ) ;
2005-09-28 20:03:15 +04:00
if ( ! IS_ERR ( key_ref ) ) {
ret = key_ref_to_ptr ( key_ref ) - > serial ;
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
}
else {
2005-09-28 20:03:15 +04:00
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-28 20:03:15 +04:00
key_ref_put ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
error3 :
2008-04-29 12:01:19 +04:00
if ( ! vm )
kfree ( payload ) ;
else
vfree ( payload ) ;
2005-04-17 02:20:36 +04:00
error2 :
kfree ( description ) ;
error :
return ret ;
} /* end sys_add_key() */
/*****************************************************************************/
/*
* search the process keyrings for a matching key
* - nested keyrings may also be searched if they have Search permission
* - if a key is found , it will be attached to the destination keyring if
* there ' s one specified
* - / sbin / request - key will be invoked if _callout_info is non - NULL
* - the _callout_info string will be passed to / sbin / request - key
* - if the _callout_info string is empty , it will be rendered as " - "
* - implements request_key ( )
*/
asmlinkage long sys_request_key ( const char __user * _type ,
const char __user * _description ,
const char __user * _callout_info ,
key_serial_t destringid )
{
struct key_type * ktype ;
2005-09-28 20:03:15 +04:00
struct key * key ;
key_ref_t dest_ref ;
2008-04-29 12:01:24 +04:00
size_t callout_len ;
2005-04-17 02:20:36 +04:00
char type [ 32 ] , * description , * callout_info ;
2006-03-24 14:18:43 +03:00
long ret ;
2005-04-17 02:20:36 +04:00
/* pull the type into kernel space */
2006-03-24 14:18:43 +03:00
ret = key_get_type_from_user ( type , _type , sizeof ( type ) ) ;
2005-04-17 02:20:36 +04:00
if ( ret < 0 )
goto error ;
2005-08-04 14:50:01 +04:00
2005-04-17 02:20:36 +04:00
/* pull the description into kernel space */
2006-03-24 14:18:43 +03:00
description = strndup_user ( _description , PAGE_SIZE ) ;
if ( IS_ERR ( description ) ) {
ret = PTR_ERR ( description ) ;
2005-04-17 02:20:36 +04:00
goto error ;
2006-03-24 14:18:43 +03:00
}
2005-04-17 02:20:36 +04:00
/* pull the callout info into kernel space */
callout_info = NULL ;
2008-04-29 12:01:24 +04:00
callout_len = 0 ;
2005-04-17 02:20:36 +04:00
if ( _callout_info ) {
2006-03-24 14:18:43 +03:00
callout_info = strndup_user ( _callout_info , PAGE_SIZE ) ;
if ( IS_ERR ( callout_info ) ) {
ret = PTR_ERR ( callout_info ) ;
2005-04-17 02:20:36 +04:00
goto error2 ;
2006-03-24 14:18:43 +03:00
}
2008-04-29 12:01:24 +04:00
callout_len = strlen ( callout_info ) ;
2005-04-17 02:20:36 +04:00
}
/* get the destination keyring if specified */
2005-09-28 20:03:15 +04:00
dest_ref = NULL ;
2005-04-17 02:20:36 +04:00
if ( destringid ) {
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
dest_ref = lookup_user_key ( destringid , 1 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( dest_ref ) ) {
ret = PTR_ERR ( dest_ref ) ;
2005-04-17 02:20:36 +04:00
goto error3 ;
}
}
/* find the key type */
ktype = key_type_lookup ( type ) ;
if ( IS_ERR ( ktype ) ) {
ret = PTR_ERR ( ktype ) ;
goto error4 ;
}
/* do the search */
2008-04-29 12:01:24 +04:00
key = request_key_and_link ( ktype , description , callout_info ,
callout_len , NULL , key_ref_to_ptr ( dest_ref ) ,
2006-06-26 11:24:50 +04:00
KEY_ALLOC_IN_QUOTA ) ;
2005-04-17 02:20:36 +04:00
if ( IS_ERR ( key ) ) {
ret = PTR_ERR ( key ) ;
goto error5 ;
}
ret = key - > serial ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
key_put ( key ) ;
2005-04-17 02:20:36 +04:00
error5 :
key_type_put ( ktype ) ;
error4 :
2005-09-28 20:03:15 +04:00
key_ref_put ( dest_ref ) ;
2005-04-17 02:20:36 +04:00
error3 :
kfree ( callout_info ) ;
error2 :
kfree ( description ) ;
error :
return ret ;
} /* end sys_request_key() */
/*****************************************************************************/
/*
* get the ID of the specified process keyring
* - the keyring must have search permission to be found
* - implements keyctl ( KEYCTL_GET_KEYRING_ID )
*/
long keyctl_get_keyring_ID ( key_serial_t id , int create )
{
2005-09-28 20:03:15 +04:00
key_ref_t key_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , create , 0 , KEY_SEARCH ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
2005-09-28 20:03:15 +04:00
ret = key_ref_to_ptr ( key_ref ) - > serial ;
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
error :
return ret ;
} /* end keyctl_get_keyring_ID() */
/*****************************************************************************/
/*
* join the session keyring
* - implements keyctl ( KEYCTL_JOIN_SESSION_KEYRING )
*/
long keyctl_join_session_keyring ( const char __user * _name )
{
char * name ;
2006-03-24 14:18:43 +03:00
long ret ;
2005-04-17 02:20:36 +04:00
/* fetch the name from userspace */
name = NULL ;
if ( _name ) {
2006-03-24 14:18:43 +03:00
name = strndup_user ( _name , PAGE_SIZE ) ;
if ( IS_ERR ( name ) ) {
ret = PTR_ERR ( name ) ;
2005-04-17 02:20:36 +04:00
goto error ;
2006-03-24 14:18:43 +03:00
}
2005-04-17 02:20:36 +04:00
}
/* join the session */
ret = join_session_keyring ( name ) ;
error :
return ret ;
} /* end keyctl_join_session_keyring() */
/*****************************************************************************/
/*
* update a key ' s data payload
* - the key must be writable
* - implements keyctl ( KEYCTL_UPDATE )
*/
long keyctl_update_key ( key_serial_t id ,
const void __user * _payload ,
size_t plen )
{
2005-09-28 20:03:15 +04:00
key_ref_t key_ref ;
2005-04-17 02:20:36 +04:00
void * payload ;
long ret ;
ret = - EINVAL ;
if ( plen > PAGE_SIZE )
goto error ;
/* pull the payload in if one was supplied */
payload = NULL ;
if ( _payload ) {
ret = - ENOMEM ;
payload = kmalloc ( plen , GFP_KERNEL ) ;
if ( ! payload )
goto error ;
ret = - EFAULT ;
if ( copy_from_user ( payload , _payload , plen ) ! = 0 )
goto error2 ;
}
/* find the target key (which must be writable) */
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , 0 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error2 ;
}
/* update the key */
2005-09-28 20:03:15 +04:00
ret = key_update ( key_ref , payload , plen ) ;
2005-04-17 02:20:36 +04:00
2005-09-28 20:03:15 +04:00
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
error2 :
kfree ( payload ) ;
error :
return ret ;
} /* end keyctl_update_key() */
/*****************************************************************************/
/*
* revoke a key
* - the key must be writable
* - implements keyctl ( KEYCTL_REVOKE )
*/
long keyctl_revoke_key ( key_serial_t id )
{
2005-09-28 20:03:15 +04:00
key_ref_t key_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , 0 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
2005-09-28 20:03:15 +04:00
key_revoke ( key_ref_to_ptr ( key_ref ) ) ;
2005-04-17 02:20:36 +04:00
ret = 0 ;
2005-09-28 20:03:15 +04:00
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
error :
2005-08-04 14:50:01 +04:00
return ret ;
2005-04-17 02:20:36 +04:00
} /* end keyctl_revoke_key() */
/*****************************************************************************/
/*
* clear the specified process keyring
* - the keyring must be writable
* - implements keyctl ( KEYCTL_CLEAR )
*/
long keyctl_keyring_clear ( key_serial_t ringid )
{
2005-09-28 20:03:15 +04:00
key_ref_t keyring_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
keyring_ref = lookup_user_key ( ringid , 1 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( keyring_ref ) ) {
ret = PTR_ERR ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
2005-09-28 20:03:15 +04:00
ret = keyring_clear ( key_ref_to_ptr ( keyring_ref ) ) ;
2005-04-17 02:20:36 +04:00
2005-09-28 20:03:15 +04:00
key_ref_put ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
error :
return ret ;
} /* end keyctl_keyring_clear() */
/*****************************************************************************/
/*
* link a key into a keyring
* - the keyring must be writable
* - the key must be linkable
* - implements keyctl ( KEYCTL_LINK )
*/
long keyctl_keyring_link ( key_serial_t id , key_serial_t ringid )
{
2005-09-28 20:03:15 +04:00
key_ref_t keyring_ref , key_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
keyring_ref = lookup_user_key ( ringid , 1 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( keyring_ref ) ) {
ret = PTR_ERR ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , 1 , 0 , KEY_LINK ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error2 ;
}
2005-09-28 20:03:15 +04:00
ret = key_link ( key_ref_to_ptr ( keyring_ref ) , key_ref_to_ptr ( key_ref ) ) ;
2005-04-17 02:20:36 +04:00
2005-09-28 20:03:15 +04:00
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
error2 :
2005-09-28 20:03:15 +04:00
key_ref_put ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
error :
return ret ;
} /* end keyctl_keyring_link() */
/*****************************************************************************/
/*
* unlink the first attachment of a key from a keyring
* - the keyring must be writable
* - we don ' t need any permissions on the key
* - implements keyctl ( KEYCTL_UNLINK )
*/
long keyctl_keyring_unlink ( key_serial_t id , key_serial_t ringid )
{
2005-09-28 20:03:15 +04:00
key_ref_t keyring_ref , key_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
keyring_ref = lookup_user_key ( ringid , 0 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( keyring_ref ) ) {
ret = PTR_ERR ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , 0 , 0 , 0 ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error2 ;
}
2005-09-28 20:03:15 +04:00
ret = key_unlink ( key_ref_to_ptr ( keyring_ref ) , key_ref_to_ptr ( key_ref ) ) ;
2005-04-17 02:20:36 +04:00
2005-09-28 20:03:15 +04:00
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
error2 :
2005-09-28 20:03:15 +04:00
key_ref_put ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
error :
return ret ;
} /* end keyctl_keyring_unlink() */
/*****************************************************************************/
/*
* describe a user key
* - the key must have view permission
* - if there ' s a buffer , we place up to buflen bytes of data into it
* - unless there ' s an error , we return the amount of description available ,
* irrespective of how much we may have copied
* - the description is formatted thus :
* type ; uid ; gid ; perm ; description < NUL >
* - implements keyctl ( KEYCTL_DESCRIBE )
*/
long keyctl_describe_key ( key_serial_t keyid ,
char __user * buffer ,
size_t buflen )
{
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
struct key * key , * instkey ;
2005-09-28 20:03:15 +04:00
key_ref_t key_ref ;
2005-04-17 02:20:36 +04:00
char * tmpbuf ;
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( keyid , 0 , 1 , KEY_VIEW ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
/* viewing a key under construction is permitted if we have the
* authorisation token handy */
2005-09-28 20:03:15 +04:00
if ( PTR_ERR ( key_ref ) = = - EACCES ) {
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
instkey = key_get_instantiation_authkey ( keyid ) ;
if ( ! IS_ERR ( instkey ) ) {
key_put ( instkey ) ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( keyid ,
2005-09-28 20:03:15 +04:00
0 , 1 , 0 ) ;
if ( ! IS_ERR ( key_ref ) )
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
goto okay ;
}
}
2005-09-28 20:03:15 +04:00
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
okay :
2005-04-17 02:20:36 +04:00
/* calculate how much description we're going to return */
ret = - ENOMEM ;
tmpbuf = kmalloc ( PAGE_SIZE , GFP_KERNEL ) ;
if ( ! tmpbuf )
goto error2 ;
2005-09-28 20:03:15 +04:00
key = key_ref_to_ptr ( key_ref ) ;
2005-04-17 02:20:36 +04:00
ret = snprintf ( tmpbuf , PAGE_SIZE - 1 ,
2005-09-28 20:03:15 +04:00
" %s;%d;%d;%08x;%s " ,
key_ref_to_ptr ( key_ref ) - > type - > name ,
key_ref_to_ptr ( key_ref ) - > uid ,
key_ref_to_ptr ( key_ref ) - > gid ,
key_ref_to_ptr ( key_ref ) - > perm ,
key_ref_to_ptr ( key_ref ) - > description ?
key_ref_to_ptr ( key_ref ) - > description : " "
2005-04-17 02:20:36 +04:00
) ;
/* include a NUL char at the end of the data */
if ( ret > PAGE_SIZE - 1 )
ret = PAGE_SIZE - 1 ;
tmpbuf [ ret ] = 0 ;
ret + + ;
/* consider returning the data */
if ( buffer & & buflen > 0 ) {
if ( buflen > ret )
buflen = ret ;
if ( copy_to_user ( buffer , tmpbuf , buflen ) ! = 0 )
ret = - EFAULT ;
}
kfree ( tmpbuf ) ;
error2 :
2005-09-28 20:03:15 +04:00
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
error :
return ret ;
} /* end keyctl_describe_key() */
/*****************************************************************************/
/*
* search the specified keyring for a matching key
* - the start keyring must be searchable
* - nested keyrings may also be searched if they are searchable
* - only keys with search permission may be found
* - if a key is found , it will be attached to the destination keyring if
* there ' s one specified
* - implements keyctl ( KEYCTL_SEARCH )
*/
long keyctl_keyring_search ( key_serial_t ringid ,
const char __user * _type ,
const char __user * _description ,
key_serial_t destringid )
{
struct key_type * ktype ;
2005-09-28 20:03:15 +04:00
key_ref_t keyring_ref , key_ref , dest_ref ;
2005-04-17 02:20:36 +04:00
char type [ 32 ] , * description ;
2006-03-24 14:18:43 +03:00
long ret ;
2005-04-17 02:20:36 +04:00
/* pull the type and description into kernel space */
2006-03-24 14:18:43 +03:00
ret = key_get_type_from_user ( type , _type , sizeof ( type ) ) ;
2005-04-17 02:20:36 +04:00
if ( ret < 0 )
goto error ;
2006-03-24 14:18:43 +03:00
description = strndup_user ( _description , PAGE_SIZE ) ;
if ( IS_ERR ( description ) ) {
ret = PTR_ERR ( description ) ;
2005-04-17 02:20:36 +04:00
goto error ;
2006-03-24 14:18:43 +03:00
}
2005-04-17 02:20:36 +04:00
/* get the keyring at which to begin the search */
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
keyring_ref = lookup_user_key ( ringid , 0 , 0 , KEY_SEARCH ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( keyring_ref ) ) {
ret = PTR_ERR ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
goto error2 ;
}
/* get the destination keyring if specified */
2005-09-28 20:03:15 +04:00
dest_ref = NULL ;
2005-04-17 02:20:36 +04:00
if ( destringid ) {
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
dest_ref = lookup_user_key ( destringid , 1 , 0 , KEY_WRITE ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( dest_ref ) ) {
ret = PTR_ERR ( dest_ref ) ;
2005-04-17 02:20:36 +04:00
goto error3 ;
}
}
/* find the key type */
ktype = key_type_lookup ( type ) ;
if ( IS_ERR ( ktype ) ) {
ret = PTR_ERR ( ktype ) ;
goto error4 ;
}
/* do the search */
2005-09-28 20:03:15 +04:00
key_ref = keyring_search ( keyring_ref , ktype , description ) ;
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
/* treat lack or presence of a negative key the same */
if ( ret = = - EAGAIN )
ret = - ENOKEY ;
goto error5 ;
}
/* link the resulting key to the destination keyring if we can */
2005-09-28 20:03:15 +04:00
if ( dest_ref ) {
2005-10-31 02:02:44 +03:00
ret = key_permission ( key_ref , KEY_LINK ) ;
if ( ret < 0 )
2005-04-17 02:20:36 +04:00
goto error6 ;
2005-09-28 20:03:15 +04:00
ret = key_link ( key_ref_to_ptr ( dest_ref ) , key_ref_to_ptr ( key_ref ) ) ;
2005-04-17 02:20:36 +04:00
if ( ret < 0 )
goto error6 ;
}
2005-09-28 20:03:15 +04:00
ret = key_ref_to_ptr ( key_ref ) - > serial ;
2005-04-17 02:20:36 +04:00
error6 :
2005-09-28 20:03:15 +04:00
key_ref_put ( key_ref ) ;
2005-04-17 02:20:36 +04:00
error5 :
key_type_put ( ktype ) ;
error4 :
2005-09-28 20:03:15 +04:00
key_ref_put ( dest_ref ) ;
2005-04-17 02:20:36 +04:00
error3 :
2005-09-28 20:03:15 +04:00
key_ref_put ( keyring_ref ) ;
2005-04-17 02:20:36 +04:00
error2 :
kfree ( description ) ;
error :
return ret ;
} /* end keyctl_keyring_search() */
/*****************************************************************************/
/*
* read a user key ' s payload
* - the keyring must be readable or the key must be searchable from the
* process ' s keyrings
* - if there ' s a buffer , we place up to buflen bytes of data into it
* - unless there ' s an error , we return the amount of data in the key ,
* irrespective of how much we may have copied
* - implements keyctl ( KEYCTL_READ )
*/
long keyctl_read_key ( key_serial_t keyid , char __user * buffer , size_t buflen )
{
2005-09-28 20:03:15 +04:00
struct key * key ;
key_ref_t key_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
/* find the key first */
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( keyid , 0 , 0 , 0 ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = - ENOKEY ;
goto error ;
2005-04-17 02:20:36 +04:00
}
2005-09-28 20:03:15 +04:00
key = key_ref_to_ptr ( key_ref ) ;
/* see if we can read it directly */
2005-10-31 02:02:44 +03:00
ret = key_permission ( key_ref , KEY_READ ) ;
if ( ret = = 0 )
2005-09-28 20:03:15 +04:00
goto can_read_key ;
2005-10-31 02:02:44 +03:00
if ( ret ! = - EACCES )
goto error ;
2005-09-28 20:03:15 +04:00
/* we can't; see if it's searchable from this process's keyrings
* - we automatically take account of the fact that it may be
* dangling off an instantiation key
*/
if ( ! is_key_possessed ( key_ref ) ) {
ret = - EACCES ;
goto error2 ;
}
2005-04-17 02:20:36 +04:00
/* the key is probably readable - now try to read it */
can_read_key :
ret = key_validate ( key ) ;
if ( ret = = 0 ) {
ret = - EOPNOTSUPP ;
if ( key - > type - > read ) {
/* read the data with the semaphore held (since we
* might sleep ) */
down_read ( & key - > sem ) ;
ret = key - > type - > read ( key , buffer , buflen ) ;
up_read ( & key - > sem ) ;
}
}
error2 :
key_put ( key ) ;
error :
return ret ;
} /* end keyctl_read_key() */
/*****************************************************************************/
/*
* change the ownership of a key
* - the keyring owned by the changer
* - if the uid or gid is - 1 , then that parameter is not changed
* - implements keyctl ( KEYCTL_CHOWN )
*/
long keyctl_chown_key ( key_serial_t id , uid_t uid , gid_t gid )
{
2006-06-26 11:24:51 +04:00
struct key_user * newowner , * zapowner = NULL ;
2005-04-17 02:20:36 +04:00
struct key * key ;
2005-09-28 20:03:15 +04:00
key_ref_t key_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
ret = 0 ;
if ( uid = = ( uid_t ) - 1 & & gid = = ( gid_t ) - 1 )
goto error ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , 1 , 1 , KEY_SETATTR ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
2005-09-28 20:03:15 +04:00
key = key_ref_to_ptr ( key_ref ) ;
2005-04-17 02:20:36 +04:00
/* make the changes with the locks held to prevent chown/chown races */
ret = - EACCES ;
down_write ( & key - > sem ) ;
if ( ! capable ( CAP_SYS_ADMIN ) ) {
/* only the sysadmin can chown a key to some other UID */
if ( uid ! = ( uid_t ) - 1 & & key - > uid ! = uid )
2006-06-26 11:24:51 +04:00
goto error_put ;
2005-04-17 02:20:36 +04:00
/* only the sysadmin can set the key's GID to a group other
* than one of those that the current process subscribes to */
if ( gid ! = ( gid_t ) - 1 & & gid ! = key - > gid & & ! in_group_p ( gid ) )
2006-06-26 11:24:51 +04:00
goto error_put ;
2005-04-17 02:20:36 +04:00
}
2006-06-26 11:24:51 +04:00
/* change the UID */
2005-04-17 02:20:36 +04:00
if ( uid ! = ( uid_t ) - 1 & & uid ! = key - > uid ) {
2006-06-26 11:24:51 +04:00
ret = - ENOMEM ;
newowner = key_user_lookup ( uid ) ;
if ( ! newowner )
goto error_put ;
/* transfer the quota burden to the new user */
if ( test_bit ( KEY_FLAG_IN_QUOTA , & key - > flags ) ) {
2008-04-29 12:01:32 +04:00
unsigned maxkeys = ( uid = = 0 ) ?
key_quota_root_maxkeys : key_quota_maxkeys ;
unsigned maxbytes = ( uid = = 0 ) ?
key_quota_root_maxbytes : key_quota_maxbytes ;
2006-06-26 11:24:51 +04:00
spin_lock ( & newowner - > lock ) ;
2008-04-29 12:01:32 +04:00
if ( newowner - > qnkeys + 1 > = maxkeys | |
newowner - > qnbytes + key - > quotalen > = maxbytes | |
newowner - > qnbytes + key - > quotalen <
newowner - > qnbytes )
2006-06-26 11:24:51 +04:00
goto quota_overrun ;
newowner - > qnkeys + + ;
newowner - > qnbytes + = key - > quotalen ;
spin_unlock ( & newowner - > lock ) ;
spin_lock ( & key - > user - > lock ) ;
key - > user - > qnkeys - - ;
key - > user - > qnbytes - = key - > quotalen ;
spin_unlock ( & key - > user - > lock ) ;
}
atomic_dec ( & key - > user - > nkeys ) ;
atomic_inc ( & newowner - > nkeys ) ;
if ( test_bit ( KEY_FLAG_INSTANTIATED , & key - > flags ) ) {
atomic_dec ( & key - > user - > nikeys ) ;
atomic_inc ( & newowner - > nikeys ) ;
}
zapowner = key - > user ;
key - > user = newowner ;
key - > uid = uid ;
2005-04-17 02:20:36 +04:00
}
/* change the GID */
if ( gid ! = ( gid_t ) - 1 )
key - > gid = gid ;
ret = 0 ;
2006-06-26 11:24:51 +04:00
error_put :
2005-04-17 02:20:36 +04:00
up_write ( & key - > sem ) ;
key_put ( key ) ;
2006-06-26 11:24:51 +04:00
if ( zapowner )
key_user_put ( zapowner ) ;
error :
2005-04-17 02:20:36 +04:00
return ret ;
2006-06-26 11:24:51 +04:00
quota_overrun :
spin_unlock ( & newowner - > lock ) ;
zapowner = newowner ;
ret = - EDQUOT ;
goto error_put ;
2005-04-17 02:20:36 +04:00
} /* end keyctl_chown_key() */
/*****************************************************************************/
/*
* change the permission mask on a key
* - the keyring owned by the changer
* - implements keyctl ( KEYCTL_SETPERM )
*/
long keyctl_setperm_key ( key_serial_t id , key_perm_t perm )
{
struct key * key ;
2005-09-28 20:03:15 +04:00
key_ref_t key_ref ;
2005-04-17 02:20:36 +04:00
long ret ;
ret = - EINVAL ;
2005-09-28 20:03:15 +04:00
if ( perm & ~ ( KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL ) )
2005-04-17 02:20:36 +04:00
goto error ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , 1 , 1 , KEY_SETATTR ) ;
2005-09-28 20:03:15 +04:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
2005-04-17 02:20:36 +04:00
goto error ;
}
2005-09-28 20:03:15 +04:00
key = key_ref_to_ptr ( key_ref ) ;
2005-06-24 09:00:49 +04:00
/* make the changes with the locks held to prevent chown/chmod races */
2005-04-17 02:20:36 +04:00
ret = - EACCES ;
down_write ( & key - > sem ) ;
2005-06-24 09:00:49 +04:00
/* if we're not the sysadmin, we can only change a key that we own */
2008-11-14 02:39:11 +03:00
if ( capable ( CAP_SYS_ADMIN ) | | key - > uid = = current_fsuid ( ) ) {
2005-06-24 09:00:49 +04:00
key - > perm = perm ;
ret = 0 ;
}
2005-04-17 02:20:36 +04:00
up_write ( & key - > sem ) ;
key_put ( key ) ;
2005-06-24 09:00:49 +04:00
error :
2005-04-17 02:20:36 +04:00
return ret ;
} /* end keyctl_setperm_key() */
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
/*
* get the destination keyring for instantiation
*/
static long get_instantiation_keyring ( key_serial_t ringid ,
struct request_key_auth * rka ,
struct key * * _dest_keyring )
{
key_ref_t dkref ;
/* just return a NULL pointer if we weren't asked to make a link */
if ( ringid = = 0 ) {
* _dest_keyring = NULL ;
return 0 ;
}
/* if a specific keyring is nominated by ID, then use that */
if ( ringid > 0 ) {
dkref = lookup_user_key ( ringid , 1 , 0 , KEY_WRITE ) ;
if ( IS_ERR ( dkref ) )
return PTR_ERR ( dkref ) ;
* _dest_keyring = key_ref_to_ptr ( dkref ) ;
return 0 ;
}
if ( ringid = = KEY_SPEC_REQKEY_AUTH_KEY )
return - EINVAL ;
/* otherwise specify the destination keyring recorded in the
* authorisation key ( any KEY_SPEC_ * _KEYRING ) */
if ( ringid > = KEY_SPEC_REQUESTOR_KEYRING ) {
* _dest_keyring = rka - > dest_keyring ;
return 0 ;
}
return - ENOKEY ;
}
2005-04-17 02:20:36 +04:00
/*****************************************************************************/
/*
* instantiate the key with the specified payload , and , if one is given , link
* the key into the keyring
*/
long keyctl_instantiate_key ( key_serial_t id ,
const void __user * _payload ,
size_t plen ,
key_serial_t ringid )
{
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
struct request_key_auth * rka ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
struct key * instkey , * dest_keyring ;
2005-04-17 02:20:36 +04:00
void * payload ;
long ret ;
2008-04-29 12:01:19 +04:00
bool vm = false ;
2005-04-17 02:20:36 +04:00
ret = - EINVAL ;
2008-04-29 12:01:19 +04:00
if ( plen > 1024 * 1024 - 1 )
2005-04-17 02:20:36 +04:00
goto error ;
2006-01-08 12:02:47 +03:00
/* the appropriate instantiation authorisation key must have been
* assumed before calling this */
ret = - EPERM ;
2008-11-14 02:39:16 +03:00
instkey = current - > cred - > request_key_auth ;
2006-01-08 12:02:47 +03:00
if ( ! instkey )
goto error ;
rka = instkey - > payload . data ;
if ( rka - > target_key - > serial ! = id )
goto error ;
2005-04-17 02:20:36 +04:00
/* pull the payload in if one was supplied */
payload = NULL ;
if ( _payload ) {
ret = - ENOMEM ;
payload = kmalloc ( plen , GFP_KERNEL ) ;
2008-04-29 12:01:19 +04:00
if ( ! payload ) {
if ( plen < = PAGE_SIZE )
goto error ;
vm = true ;
payload = vmalloc ( plen ) ;
if ( ! payload )
goto error ;
}
2005-04-17 02:20:36 +04:00
ret = - EFAULT ;
if ( copy_from_user ( payload , _payload , plen ) ! = 0 )
goto error2 ;
}
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
/* find the destination keyring amongst those belonging to the
* requesting task */
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
ret = get_instantiation_keyring ( ringid , rka , & dest_keyring ) ;
if ( ret < 0 )
goto error2 ;
2005-04-17 02:20:36 +04:00
/* instantiate the key and link it into a keyring */
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
ret = key_instantiate_and_link ( rka - > target_key , payload , plen ,
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
dest_keyring , instkey ) ;
2005-04-17 02:20:36 +04:00
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_put ( dest_keyring ) ;
2006-01-08 12:02:47 +03:00
/* discard the assumed authority if it's just been disabled by
* instantiation of the key */
if ( ret = = 0 ) {
2008-11-14 02:39:16 +03:00
key_put ( current - > cred - > request_key_auth ) ;
current - > cred - > request_key_auth = NULL ;
2006-01-08 12:02:47 +03:00
}
error2 :
2008-04-29 12:01:19 +04:00
if ( ! vm )
kfree ( payload ) ;
else
vfree ( payload ) ;
2006-01-08 12:02:47 +03:00
error :
2005-04-17 02:20:36 +04:00
return ret ;
} /* end keyctl_instantiate_key() */
/*****************************************************************************/
/*
* negatively instantiate the key with the given timeout ( in seconds ) , and , if
* one is given , link the key into the keyring
*/
long keyctl_negate_key ( key_serial_t id , unsigned timeout , key_serial_t ringid )
{
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
struct request_key_auth * rka ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
struct key * instkey , * dest_keyring ;
2005-04-17 02:20:36 +04:00
long ret ;
2006-01-08 12:02:47 +03:00
/* the appropriate instantiation authorisation key must have been
* assumed before calling this */
ret = - EPERM ;
2008-11-14 02:39:16 +03:00
instkey = current - > cred - > request_key_auth ;
2006-01-08 12:02:47 +03:00
if ( ! instkey )
2005-04-17 02:20:36 +04:00
goto error ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
rka = instkey - > payload . data ;
2006-01-08 12:02:47 +03:00
if ( rka - > target_key - > serial ! = id )
goto error ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
2005-04-17 02:20:36 +04:00
/* find the destination keyring if present (which must also be
* writable ) */
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
ret = get_instantiation_keyring ( ringid , rka , & dest_keyring ) ;
if ( ret < 0 )
goto error ;
2005-04-17 02:20:36 +04:00
/* instantiate the key and link it into a keyring */
2005-09-28 20:03:15 +04:00
ret = key_negate_and_link ( rka - > target_key , timeout ,
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
dest_keyring , instkey ) ;
2005-04-17 02:20:36 +04:00
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_put ( dest_keyring ) ;
2006-01-08 12:02:47 +03:00
/* discard the assumed authority if it's just been disabled by
* instantiation of the key */
if ( ret = = 0 ) {
2008-11-14 02:39:16 +03:00
key_put ( current - > cred - > request_key_auth ) ;
current - > cred - > request_key_auth = NULL ;
2006-01-08 12:02:47 +03:00
}
error :
2005-04-17 02:20:36 +04:00
return ret ;
} /* end keyctl_negate_key() */
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
/*****************************************************************************/
/*
* set the default keyring in which request_key ( ) will cache keys
* - return the old setting
*/
long keyctl_set_reqkey_keyring ( int reqkey_defl )
{
2008-11-14 02:39:16 +03:00
struct cred * cred = current - > cred ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
int ret ;
switch ( reqkey_defl ) {
case KEY_REQKEY_DEFL_THREAD_KEYRING :
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
ret = install_thread_keyring ( ) ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
if ( ret < 0 )
return ret ;
goto set ;
case KEY_REQKEY_DEFL_PROCESS_KEYRING :
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
ret = install_process_keyring ( ) ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
if ( ret < 0 )
return ret ;
case KEY_REQKEY_DEFL_DEFAULT :
case KEY_REQKEY_DEFL_SESSION_KEYRING :
case KEY_REQKEY_DEFL_USER_KEYRING :
case KEY_REQKEY_DEFL_USER_SESSION_KEYRING :
set :
2008-11-14 02:39:16 +03:00
cred - > jit_keyring = reqkey_defl ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
case KEY_REQKEY_DEFL_NO_CHANGE :
2008-11-14 02:39:16 +03:00
return cred - > jit_keyring ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
case KEY_REQKEY_DEFL_GROUP_KEYRING :
default :
return - EINVAL ;
}
} /* end keyctl_set_reqkey_keyring() */
2006-01-08 12:02:43 +03:00
/*****************************************************************************/
/*
* set or clear the timeout for a key
*/
long keyctl_set_timeout ( key_serial_t id , unsigned timeout )
{
struct timespec now ;
struct key * key ;
key_ref_t key_ref ;
time_t expiry ;
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( id , 1 , 1 , KEY_SETATTR ) ;
2006-01-08 12:02:43 +03:00
if ( IS_ERR ( key_ref ) ) {
ret = PTR_ERR ( key_ref ) ;
goto error ;
}
key = key_ref_to_ptr ( key_ref ) ;
/* make the changes with the locks held to prevent races */
down_write ( & key - > sem ) ;
expiry = 0 ;
if ( timeout > 0 ) {
now = current_kernel_time ( ) ;
expiry = now . tv_sec + timeout ;
}
key - > expiry = expiry ;
up_write ( & key - > sem ) ;
key_put ( key ) ;
ret = 0 ;
error :
return ret ;
} /* end keyctl_set_timeout() */
2006-01-08 12:02:47 +03:00
/*****************************************************************************/
/*
* assume the authority to instantiate the specified key
*/
long keyctl_assume_authority ( key_serial_t id )
{
struct key * authkey ;
long ret ;
/* special key IDs aren't permitted */
ret = - EINVAL ;
if ( id < 0 )
goto error ;
/* we divest ourselves of authority if given an ID of 0 */
if ( id = = 0 ) {
2008-11-14 02:39:16 +03:00
key_put ( current - > cred - > request_key_auth ) ;
current - > cred - > request_key_auth = NULL ;
2006-01-08 12:02:47 +03:00
ret = 0 ;
goto error ;
}
/* attempt to assume the authority temporarily granted to us whilst we
* instantiate the specified key
* - the authorisation key must be in the current task ' s keyrings
* somewhere
*/
authkey = key_get_instantiation_authkey ( id ) ;
if ( IS_ERR ( authkey ) ) {
ret = PTR_ERR ( authkey ) ;
goto error ;
}
2008-11-14 02:39:16 +03:00
key_put ( current - > cred - > request_key_auth ) ;
current - > cred - > request_key_auth = authkey ;
2006-01-08 12:02:47 +03:00
ret = authkey - > serial ;
error :
return ret ;
} /* end keyctl_assume_authority() */
2008-04-29 12:01:26 +04:00
/*
* get the security label of a key
* - the key must grant us view permission
* - if there ' s a buffer , we place up to buflen bytes of data into it
* - unless there ' s an error , we return the amount of information available ,
* irrespective of how much we may have copied ( including the terminal NUL )
* - implements keyctl ( KEYCTL_GET_SECURITY )
*/
long keyctl_get_security ( key_serial_t keyid ,
char __user * buffer ,
size_t buflen )
{
struct key * key , * instkey ;
key_ref_t key_ref ;
char * context ;
long ret ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( keyid , 0 , 1 , KEY_VIEW ) ;
2008-04-29 12:01:26 +04:00
if ( IS_ERR ( key_ref ) ) {
if ( PTR_ERR ( key_ref ) ! = - EACCES )
return PTR_ERR ( key_ref ) ;
/* viewing a key under construction is also permitted if we
* have the authorisation token handy */
instkey = key_get_instantiation_authkey ( keyid ) ;
if ( IS_ERR ( instkey ) )
return PTR_ERR ( key_ref ) ;
key_put ( instkey ) ;
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-14 02:39:14 +03:00
key_ref = lookup_user_key ( keyid , 0 , 1 , 0 ) ;
2008-04-29 12:01:26 +04:00
if ( IS_ERR ( key_ref ) )
return PTR_ERR ( key_ref ) ;
}
key = key_ref_to_ptr ( key_ref ) ;
ret = security_key_getsecurity ( key , & context ) ;
if ( ret = = 0 ) {
/* if no information was returned, give userspace an empty
* string */
ret = 1 ;
if ( buffer & & buflen > 0 & &
copy_to_user ( buffer , " " , 1 ) ! = 0 )
ret = - EFAULT ;
} else if ( ret > 0 ) {
/* return as much data as there's room for */
if ( buffer & & buflen > 0 ) {
if ( buflen > ret )
buflen = ret ;
if ( copy_to_user ( buffer , context , buflen ) ! = 0 )
ret = - EFAULT ;
}
kfree ( context ) ;
}
key_ref_put ( key_ref ) ;
return ret ;
}
2005-04-17 02:20:36 +04:00
/*****************************************************************************/
/*
* the key control system call
*/
asmlinkage long sys_keyctl ( int option , unsigned long arg2 , unsigned long arg3 ,
unsigned long arg4 , unsigned long arg5 )
{
switch ( option ) {
case KEYCTL_GET_KEYRING_ID :
return keyctl_get_keyring_ID ( ( key_serial_t ) arg2 ,
( int ) arg3 ) ;
case KEYCTL_JOIN_SESSION_KEYRING :
return keyctl_join_session_keyring ( ( const char __user * ) arg2 ) ;
case KEYCTL_UPDATE :
return keyctl_update_key ( ( key_serial_t ) arg2 ,
( const void __user * ) arg3 ,
( size_t ) arg4 ) ;
case KEYCTL_REVOKE :
return keyctl_revoke_key ( ( key_serial_t ) arg2 ) ;
case KEYCTL_DESCRIBE :
return keyctl_describe_key ( ( key_serial_t ) arg2 ,
( char __user * ) arg3 ,
( unsigned ) arg4 ) ;
case KEYCTL_CLEAR :
return keyctl_keyring_clear ( ( key_serial_t ) arg2 ) ;
case KEYCTL_LINK :
return keyctl_keyring_link ( ( key_serial_t ) arg2 ,
( key_serial_t ) arg3 ) ;
case KEYCTL_UNLINK :
return keyctl_keyring_unlink ( ( key_serial_t ) arg2 ,
( key_serial_t ) arg3 ) ;
case KEYCTL_SEARCH :
return keyctl_keyring_search ( ( key_serial_t ) arg2 ,
( const char __user * ) arg3 ,
( const char __user * ) arg4 ,
( key_serial_t ) arg5 ) ;
case KEYCTL_READ :
return keyctl_read_key ( ( key_serial_t ) arg2 ,
( char __user * ) arg3 ,
( size_t ) arg4 ) ;
case KEYCTL_CHOWN :
return keyctl_chown_key ( ( key_serial_t ) arg2 ,
( uid_t ) arg3 ,
( gid_t ) arg4 ) ;
case KEYCTL_SETPERM :
return keyctl_setperm_key ( ( key_serial_t ) arg2 ,
( key_perm_t ) arg3 ) ;
case KEYCTL_INSTANTIATE :
return keyctl_instantiate_key ( ( key_serial_t ) arg2 ,
( const void __user * ) arg3 ,
( size_t ) arg4 ,
( key_serial_t ) arg5 ) ;
case KEYCTL_NEGATE :
return keyctl_negate_key ( ( key_serial_t ) arg2 ,
( unsigned ) arg3 ,
( key_serial_t ) arg4 ) ;
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 09:00:56 +04:00
case KEYCTL_SET_REQKEY_KEYRING :
return keyctl_set_reqkey_keyring ( arg2 ) ;
2006-01-08 12:02:43 +03:00
case KEYCTL_SET_TIMEOUT :
return keyctl_set_timeout ( ( key_serial_t ) arg2 ,
( unsigned ) arg3 ) ;
2006-01-08 12:02:47 +03:00
case KEYCTL_ASSUME_AUTHORITY :
return keyctl_assume_authority ( ( key_serial_t ) arg2 ) ;
2008-04-29 12:01:26 +04:00
case KEYCTL_GET_SECURITY :
return keyctl_get_security ( ( key_serial_t ) arg2 ,
( char * ) arg3 ,
( size_t ) arg4 ) ;
2005-04-17 02:20:36 +04:00
default :
return - EOPNOTSUPP ;
}
} /* end sys_keyctl() */