From 5e9b2925e69bd55f07eb52bbde68ef08f2180d80 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 11 Mar 2011 01:00:30 +0000 Subject: 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 [] If is given, just the link to in the nominated keyring is removed. If is not given, all links to in the session keyring are removed. Signed-off-by: David Howells --- keyctl.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'keyctl.c') 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", "" }, { act_keyctl_clear, "clear", "" }, { act_keyctl_link, "link", " " }, - { act_keyctl_unlink, "unlink", " " }, + { act_keyctl_unlink, "unlink", " []" }, { act_keyctl_search, "search", " []" }, { act_keyctl_read, "read", "" }, { act_keyctl_pipe, "pipe", "" }, @@ -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() */ +} /*****************************************************************************/ /* -- cgit v1.2.1