summaryrefslogtreecommitdiff
path: root/keyctl.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2011-03-11 01:00:30 +0000
committerDavid Howells <dhowells@redhat.com>2011-03-11 01:00:30 +0000
commit5e9b2925e69bd55f07eb52bbde68ef08f2180d80 (patch)
tree61699664ae4741f993c351647574c6d26e01d592 /keyctl.c
parent65859d91f125bea27eab0eb5c0477c17318d0005 (diff)
downloadkeyutils-5e9b2925e69bd55f07eb52bbde68ef08f2180d80.tar.gz
keyctl: Permit unlinking of all instances of a key in session keyring tree
Permit unlinking of all instances of a key in session keyring tree by not electing not to provide a keyring ID to the unlink command. With this, the unlink command becomes: keyctl unlink <key> [<keyring>] If <keyring> is given, just the link to <key> in the nominated keyring is removed. If <keyring> is not given, all links to <key> in the session keyring are removed. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'keyctl.c')
-rw-r--r--keyctl.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/keyctl.c b/keyctl.c
index f1b108d..2e8d331 100644
--- a/keyctl.c
+++ b/keyctl.c
@@ -73,7 +73,7 @@ const struct command commands[] = {
{ act_keyctl_revoke, "revoke", "<key>" },
{ act_keyctl_clear, "clear", "<keyring>" },
{ act_keyctl_link, "link", "<key> <keyring>" },
- { act_keyctl_unlink, "unlink", "<key> <keyring>" },
+ { act_keyctl_unlink, "unlink", "<key> [<keyring>]" },
{ act_keyctl_search, "search", "<keyring> <type> <desc> [<dest_keyring>]" },
{ act_keyctl_read, "read", "<key>" },
{ act_keyctl_pipe, "pipe", "<key>" },
@@ -552,26 +552,43 @@ static int act_keyctl_link(int argc, char *argv[])
} /* end act_keyctl_link() */
-/*****************************************************************************/
/*
- * unlink a key from a keyrign
+ * Attempt to unlink a key matching the ID
+ */
+static int act_keyctl_unlink_func(key_serial_t parent, key_serial_t key,
+ char *desc, int desc_len, void *data)
+{
+ key_serial_t *target = data;
+
+ if (key == *target)
+ return keyctl_unlink(key, parent) < 0 ? 0 : 1;
+ return 0;
+}
+
+/*
+ * Unlink a key from a keyring or from the session keyring tree.
*/
static int act_keyctl_unlink(int argc, char *argv[])
{
key_serial_t keyring, key;
+ int n;
- if (argc != 3)
+ if (argc != 2 && argc != 3)
format();
key = get_key_id(argv[1]);
- keyring = get_key_id(argv[2]);
- if (keyctl_unlink(key, keyring) < 0)
- error("keyctl_unlink");
+ if (argc == 3) {
+ keyring = get_key_id(argv[2]);
+ if (keyctl_unlink(key, keyring) < 0)
+ error("keyctl_unlink");
+ } else {
+ n = recursive_session_key_scan(act_keyctl_unlink_func, &key);
+ printf("%d links removed\n", n);
+ }
return 0;
-
-} /* end act_keyctl_unlink() */
+}
/*****************************************************************************/
/*