diff options
author | David Howells <dhowells@redhat.com> | 2006-01-08 04:02:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:13:53 -0500 |
commit | 017679c4d45783158dba1dd6f79e712c22bb3d9a (patch) | |
tree | a536f0b581eacd88a64077f5ff15b29d23fc6405 /security/keys/keyctl.c | |
parent | cd140a5c1f456f50897af4a2e9a23d228a5fe719 (diff) |
[PATCH] keys: Permit key expiry time to be set
Add a new keyctl function that allows the expiry time to be set on a key or
removed from a key, provided the caller has attribute modification access.
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Alexander Zangerl <az@bond.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index b7a468fabdf9..299f0ae11cf0 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -967,6 +967,46 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) | |||
967 | 967 | ||
968 | /*****************************************************************************/ | 968 | /*****************************************************************************/ |
969 | /* | 969 | /* |
970 | * set or clear the timeout for a key | ||
971 | */ | ||
972 | long keyctl_set_timeout(key_serial_t id, unsigned timeout) | ||
973 | { | ||
974 | struct timespec now; | ||
975 | struct key *key; | ||
976 | key_ref_t key_ref; | ||
977 | time_t expiry; | ||
978 | long ret; | ||
979 | |||
980 | key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR); | ||
981 | if (IS_ERR(key_ref)) { | ||
982 | ret = PTR_ERR(key_ref); | ||
983 | goto error; | ||
984 | } | ||
985 | |||
986 | key = key_ref_to_ptr(key_ref); | ||
987 | |||
988 | /* make the changes with the locks held to prevent races */ | ||
989 | down_write(&key->sem); | ||
990 | |||
991 | expiry = 0; | ||
992 | if (timeout > 0) { | ||
993 | now = current_kernel_time(); | ||
994 | expiry = now.tv_sec + timeout; | ||
995 | } | ||
996 | |||
997 | key->expiry = expiry; | ||
998 | |||
999 | up_write(&key->sem); | ||
1000 | key_put(key); | ||
1001 | |||
1002 | ret = 0; | ||
1003 | error: | ||
1004 | return ret; | ||
1005 | |||
1006 | } /* end keyctl_set_timeout() */ | ||
1007 | |||
1008 | /*****************************************************************************/ | ||
1009 | /* | ||
970 | * the key control system call | 1010 | * the key control system call |
971 | */ | 1011 | */ |
972 | asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, | 1012 | asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, |
@@ -1038,6 +1078,10 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, | |||
1038 | case KEYCTL_SET_REQKEY_KEYRING: | 1078 | case KEYCTL_SET_REQKEY_KEYRING: |
1039 | return keyctl_set_reqkey_keyring(arg2); | 1079 | return keyctl_set_reqkey_keyring(arg2); |
1040 | 1080 | ||
1081 | case KEYCTL_SET_TIMEOUT: | ||
1082 | return keyctl_set_timeout((key_serial_t) arg2, | ||
1083 | (unsigned) arg3); | ||
1084 | |||
1041 | default: | 1085 | default: |
1042 | return -EOPNOTSUPP; | 1086 | return -EOPNOTSUPP; |
1043 | } | 1087 | } |