summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2020-07-07 16:56:53 +0100
committerDavid Howells <dhowells@redhat.com>2020-07-07 16:56:53 +0100
commitf3095f4901820d31cc5600ee46949bcdb246b3fa (patch)
tree43f12abc498a8e06f137a328662ceca15e781ec9
parentd00ed3599d5fccf81eac32eada0c1b33e67ba973 (diff)
downloadkeyutils-f3095f4901820d31cc5600ee46949bcdb246b3fa.tar.gz
Revert "Add a notification facility for watching for key changes"
This reverts commit 1aafbdcf1d60c5c9eb34fe404f9a9195c8ea415e which was from the wrong branch and expects /dev/watch_queue to be available. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--Makefile8
-rw-r--r--keyctl.c13
-rw-r--r--keyctl.h13
-rw-r--r--keyctl_watch.c499
-rw-r--r--keyutils.c5
-rw-r--r--keyutils.h3
-rw-r--r--man/keyctl.192
-rw-r--r--man/keyctl.32
-rw-r--r--man/keyctl_watch_key.3206
-rw-r--r--tests/prepare.inc.sh1
-rw-r--r--version.lds2
-rw-r--r--watch_queue.h128
12 files changed, 9 insertions, 963 deletions
diff --git a/Makefile b/Makefile
index 599b145..31677ea 100644
--- a/Makefile
+++ b/Makefile
@@ -150,11 +150,9 @@ endif
%.o: %.c keyutils.h Makefile
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
-keyctl: keyctl.o keyctl_testing.o keyctl_watch.o $(LIB_DEPENDENCY)
- $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ \
- keyctl.o keyctl_testing.o keyctl_watch.o -lkeyutils
-keyctl.o keyctl_testing.o keyctl_watch.o: keyctl.h
-keyctl_watch.o: watch_queue.h
+keyctl: keyctl.o keyctl_testing.o $(LIB_DEPENDENCY)
+ $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ keyctl.o keyctl_testing.o -lkeyutils
+keyctl.o keyctl_testing.o: keyctl.h
request-key: request-key.o $(LIB_DEPENDENCY)
$(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ $< -lkeyutils
diff --git a/keyctl.c b/keyctl.c
index cc25ac0..b17ceb4 100644
--- a/keyctl.c
+++ b/keyctl.c
@@ -139,16 +139,14 @@ static const struct command commands[] = {
{ act_keyctl_timeout, "timeout", "<key> <timeout>" },
{ act_keyctl_unlink, "unlink", "<key> [<keyring>]" },
{ act_keyctl_update, "update", "[-x] <key> <data>" },
- { act_keyctl_watch, "watch", "<key>" },
- { act_keyctl_watch_add, "watch_add", "<fd> <key>" },
- { act_keyctl_watch_rm, "watch_rm", "<fd> <key>" },
- { act_keyctl_watch_session, "watch_session", "[-n <name>] <notifylog> <gclog> <fd> <prog> [<arg1> <arg2> ...]" },
- { act_keyctl_watch_sync, "watch_sync", "<fd>" },
{ act_keyctl_test, "--test", "..." },
{ NULL, NULL, NULL }
};
static int dump_key_tree(key_serial_t keyring, const char *name, int hex_key_IDs);
+static void format(void) __attribute__((noreturn));
+void error(const char *msg) __attribute__((noreturn));
+static key_serial_t get_key_id(char *arg);
static void *read_file(const char *name, size_t *_size);
static uid_t myuid;
@@ -229,7 +227,7 @@ void do_command(int argc, char **argv,
/*
* display command format information
*/
-void format(void)
+static void format(void)
{
const struct command *cmd;
@@ -2290,7 +2288,6 @@ static const struct capability_def capabilities[] = {
{ "move_key", 0, KEYCTL_CAPS0_MOVE },
{ "ns_keyring_name", 1, KEYCTL_CAPS1_NS_KEYRING_NAME },
{ "ns_key_tag", 1, KEYCTL_CAPS1_NS_KEY_TAG },
- { "notify", 1, KEYCTL_CAPS1_NOTIFICATIONS },
{}
};
@@ -2335,7 +2332,7 @@ static void act_keyctl_supports(int argc, char *argv[])
/*
* parse a key identifier
*/
-key_serial_t get_key_id(char *arg)
+static key_serial_t get_key_id(char *arg)
{
key_serial_t id;
char *end;
diff --git a/keyctl.h b/keyctl.h
index ee86779..e061334 100644
--- a/keyctl.h
+++ b/keyctl.h
@@ -21,20 +21,9 @@ struct command {
* keyctl.c
*/
extern nr void do_command(int, char **, const struct command *, const char *);
-extern nr void format(void) __attribute__((noreturn));
-extern nr void error(const char *) __attribute__((noreturn));
-extern key_serial_t get_key_id(char *);
+extern nr void error(const char *);
/*
* keyctl_testing.c
*/
extern nr void act_keyctl_test(int, char *[]);
-
-/*
- * keyctl_watch.c
- */
-extern nr void act_keyctl_watch(int , char *[]);
-extern nr void act_keyctl_watch_add(int , char *[]);
-extern nr void act_keyctl_watch_rm(int , char *[]);
-extern nr void act_keyctl_watch_session(int , char *[]);
-extern nr void act_keyctl_watch_sync(int , char *[]);
diff --git a/keyctl_watch.c b/keyctl_watch.c
deleted file mode 100644
index 191fe51..0000000
--- a/keyctl_watch.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/* Key watching facility.
- *
- * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#define _GNU_SOURCE
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <errno.h>
-#include <poll.h>
-#include <getopt.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include "keyutils.h"
-#include <limits.h>
-#include "keyctl.h"
-#include "watch_queue.h"
-
-#define BUF_SIZE 4
-
-static int consumer_stop;
-static pid_t pid_con = -1, pid_cmd = -1;
-static key_serial_t session;
-static int watch_fd;
-static int debug;
-
-static inline bool after_eq(unsigned int a, unsigned int b)
-{
- return (signed int)(a - b) >= 0;
-}
-
-static void consumer_term(int sig)
-{
- consumer_stop = 1;
-}
-
-static void saw_key_change(FILE *log, struct watch_notification *n)
-{
- struct key_notification *k = (struct key_notification *)n;
- unsigned int len = (n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT;
-
- if (len != sizeof(struct key_notification) / WATCH_LENGTH_GRANULARITY)
- return;
-
- switch (n->subtype) {
- case NOTIFY_KEY_INSTANTIATED:
- fprintf(log, "%u inst\n", k->key_id);
- break;
- case NOTIFY_KEY_UPDATED:
- fprintf(log, "%u upd\n", k->key_id);
- break;
- case NOTIFY_KEY_LINKED:
- fprintf(log, "%u link %u\n", k->key_id, k->aux);
- break;
- case NOTIFY_KEY_UNLINKED:
- fprintf(log, "%u unlk %u\n", k->key_id, k->aux);
- break;
- case NOTIFY_KEY_CLEARED:
- fprintf(log, "%u clr\n", k->key_id);
- break;
- case NOTIFY_KEY_REVOKED:
- fprintf(log, "%u rev\n", k->key_id);
- break;
- case NOTIFY_KEY_INVALIDATED:
- fprintf(log, "%u inv\n", k->key_id);
- break;
- case NOTIFY_KEY_SETATTR:
- fprintf(log, "%u attr\n", k->key_id);
- break;
- }
-}
-
-/*
- * Handle removal notification.
- */
-static void saw_removal_notification(FILE *gc, struct watch_notification *n)
-{
- key_serial_t key = 0;
- unsigned int wp, l;
-
- l = (n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT;
- l <<= WATCH_LENGTH_GRANULARITY;
- wp = (n->info & WATCH_INFO_ID) >> WATCH_INFO_ID__SHIFT;
-
- if (l >= sizeof(struct watch_notification_removal)) {
- struct watch_notification_removal *r = (void *)n;
- key = r->id;
- }
-
- fprintf(gc, "%u gc\n", key);
- if (wp == 1)
- exit(0);
-}
-
-/*
- * Consume and display events.
- */
-static __attribute__((noreturn))
-int consumer(FILE *log, FILE *gc, int fd, struct watch_queue_buffer *buf)
-{
- struct watch_notification *n;
- struct pollfd p[1];
- unsigned int head, tail, mask = buf->meta.mask;
-
- setlinebuf(log);
- setlinebuf(gc);
- signal(SIGTERM, consumer_term);
-
- do {
- if (!consumer_stop) {
- p[0].fd = fd;
- p[0].events = POLLIN | POLLERR;
- p[0].revents = 0;
-
- if (poll(p, 1, -1) == -1) {
- if (errno == EINTR)
- continue;
- error("poll");
- }
- }
-
- while (head = __atomic_load_n(&buf->meta.head, __ATOMIC_ACQUIRE),
- tail = buf->meta.tail,
- tail != head
- ) {
- n = &buf->slots[tail & mask];
- if (debug)
- fprintf(stderr,
- "NOTIFY[%08x-%08x] ty=%06x:%02x i=%08x\n",
- head, tail, n->type, n->subtype, n->info);
-
- if ((n->info & WATCH_INFO_LENGTH) == 0) {
- fprintf(stderr, "Zero-length watch record\n");
- exit(4);
- }
-
- switch (n->type) {
- case WATCH_TYPE_META:
- switch (n->subtype) {
- case WATCH_META_REMOVAL_NOTIFICATION:
- saw_removal_notification(gc, n);
- break;
- }
- break;
- case WATCH_TYPE_KEY_NOTIFY:
- saw_key_change(log, n);
- break;
- }
-
- tail += (n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT;
- __atomic_store_n(&buf->meta.tail, tail, __ATOMIC_RELEASE);
- }
- } while (!consumer_stop);
-
- fprintf(log, "Monitoring terminated\n");
- if (gc != log)
- fprintf(gc, "Monitoring terminated\n");
- exit(0);
-}
-
-static struct watch_notification_filter filter = {
- .nr_filters = 1,
- .__reserved = 0,
- .filters = {
- [0] = {
- .type = WATCH_TYPE_KEY_NOTIFY,
- .subtype_filter[0] = UINT_MAX,
- },
- },
-};
-
-/*
- * Open the watch device and allocate a buffer.
- */
-static int open_watch(struct watch_queue_buffer **_buf)
-{
- struct watch_queue_buffer *buf;
- size_t page_size;
- int fd;
-
- fd = open("/dev/watch_queue", O_RDWR);
- if (fd == -1)
- error("/dev/watch_queue");
-
- if (ioctl(fd, IOC_WATCH_QUEUE_SET_SIZE, BUF_SIZE) == -1)
- error("/dev/watch_queue(size)");
-
- if (ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter) == -1)
- error("/dev/watch_queue(filter)");
-
- page_size = sysconf(_SC_PAGESIZE);
- buf = mmap(NULL, BUF_SIZE * page_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (buf == MAP_FAILED)
- error("mmap");
-
- *_buf = buf;
- return fd;
-}
-
-/*
- * Watch a key or keyring for changes.
- */
-void act_keyctl_watch(int argc, char *argv[])
-{
- struct watch_queue_buffer *buf;
- key_serial_t key;
- int wfd;
-
- if (argc != 2)
- format();
-
- key = get_key_id(argv[1]);
- wfd = open_watch(&buf);
-
- if (keyctl_watch_key(key, wfd, 0x01) == -1)
- error("keyctl_watch_key");
-
- consumer(stdout, stdout, wfd, buf);
-}
-
-/*
- * Add a watch on a key to the monitor created by watch_session.
- */
-void act_keyctl_watch_add(int argc, char *argv[])
-{
- key_serial_t key;
- int fd;
-
- if (argc != 3)
- format();
-
- fd = atoi(argv[1]);
- key = get_key_id(argv[2]);
-
- if (keyctl_watch_key(key, fd, 0x02) == -1)
- error("keyctl_watch_key");
- exit(0);
-}
-
-/*
- * Remove a watch on a key from the monitor created by watch_session.
- */
-void act_keyctl_watch_rm(int argc, char *argv[])
-{
- key_serial_t key;
- int fd;
-
- if (argc != 3)
- format();
-
- fd = atoi(argv[1]);
- key = get_key_id(argv[2]);
-
- if (keyctl_watch_key(key, fd, -1) == -1)
- error("keyctl_watch_key");
- exit(0);
-}
-
-static void exit_cleanup(void)
-{
- pid_t me = getpid();
- int w;
-
- if (me != pid_cmd && me != pid_con) {
- keyctl_watch_key(session, watch_fd, -1);
- if (pid_cmd != -1) {
- kill(pid_cmd, SIGTERM);
- waitpid(pid_cmd, &w, 0);
- }
- if (pid_con != -1) {
- kill(pid_con, SIGTERM);
- waitpid(pid_con, &w, 0);
- }
- }
-}
-
-static void run_command(int argc, char *argv[], int wfd)
-{
- char buf[16];
-
- pid_cmd = fork();
- if (pid_cmd == -1)
- error("fork");
- if (pid_cmd != 0)
- return;
-
- pid_cmd = -1;
- pid_con = -1;
-
- sprintf(buf, "%u", wfd);
- setenv("KEYCTL_WATCH_FD", buf, true);
-
- /* run the standard shell if no arguments */
- if (argc == 0) {
- const char *q = getenv("SHELL");
- if (!q)
- q = "/bin/sh";
- execl(q, q, NULL);
- error(q);
- }
-
- /* run the command specified */
- execvp(argv[0], argv);
- error(argv[0]);
-}
-
-/*
- * Open a logfiles.
- */
-static FILE *open_logfile(const char *logfile)
-{
- unsigned int flags;
- FILE *log;
- int lfd;
-
- log = fopen(logfile, "a");
- if (!log)
- error(logfile);
-
- lfd = fileno(log);
- flags = fcntl(lfd, F_GETFD);
- if (flags == -1)
- error("F_GETFD");
- if (fcntl(lfd, F_SETFD, flags | FD_CLOEXEC) == -1)
- error("F_SETFD");
-
- return log;
-}
-
-/*
- * Set up a new session keyring with a monitor that is exposed on an explicit
- * file descriptor in the program that it starts.
- */
-void act_keyctl_watch_session(int argc, char *argv[])
-{
- struct watch_queue_buffer *buf;
- const char *session_name = NULL;
- const char *logfile, *gcfile, *target_fd;
- unsigned int flags;
- pid_t pid;
- FILE *log, *gc;
- int wfd, tfd, opt, w, e = 0, e2 = 0;
-
- while (opt = getopt(argc, argv, "+dn:"),
- opt != -1) {
- switch (opt) {
- case 'd':
- debug = 1;
- break;
- case 'n':
- session_name = optarg;
- break;
- default:
- fprintf(stderr, "Unknown option\n");
- exit(2);
- }
- }
-
- argv += optind;
- argc -= optind;
-
- if (argc < 4)
- format();
-
- logfile = argv[0];
- gcfile = argv[1];
- target_fd = argv[2];
- tfd = atoi(target_fd);
- if (tfd < 3 || tfd > 9) {
- fprintf(stderr, "The target fd must be between 3 and 9\n");
- exit(2);
- }
-
- wfd = open_watch(&buf);
- if (wfd != tfd) {
- if (dup2(wfd, tfd) == -1)
- error("dup2");
- close(wfd);
- wfd = tfd;
- }
- watch_fd = wfd;
-
- atexit(exit_cleanup);
-
- /* We want the fd to be inherited across a fork. */
- flags = fcntl(wfd, F_GETFD);
- if (flags == -1)
- error("F_GETFD");
- if (fcntl(wfd, F_SETFD, flags & ~FD_CLOEXEC) == -1)
- error("F_SETFD");
-
- log = open_logfile(logfile);
- gc = open_logfile(gcfile);
-
- pid_con = fork();
- if (pid_con == -1)
- error("fork");
- if (pid_con == 0) {
- pid_cmd = -1;
- pid_con = -1;
- consumer(log, gc, wfd, buf);
- }
-
- /* Create a new session keyring and watch it. */
- session = keyctl_join_session_keyring(session_name);
- if (session == -1)
- error("keyctl_join_session_keyring");
-
- if (keyctl_watch_key(session, wfd, 0x01) == -1)
- error("keyctl_watch_key/session");
-
- fprintf(stderr, "Joined session keyring: %d\n", session);
-
- /* Start the command and then wait for it to finish and the
- * notification consumer to clean up.
- */
- run_command(argc - 3, argv + 3, wfd);
- close(wfd);
- wfd = -1;
-
- while (pid = wait(&w),
- pid != -1) {
- if (pid == pid_cmd) {
- if (pid_con != -1)
- kill(pid_con, SIGTERM);
- if (WIFEXITED(w)) {
- e2 = WEXITSTATUS(w);
- pid_cmd = -1;
- } else if (WIFSIGNALED(w)) {
- e2 = WTERMSIG(w) + 128;
- pid_cmd = -1;
- } else if (WIFSTOPPED(w)) {
- raise(WSTOPSIG(w));
- }
- } else if (pid == pid_con) {
- if (pid_cmd != -1)
- kill(pid_cmd, SIGTERM);
- if (WIFEXITED(w)) {
- e = WEXITSTATUS(w);
- pid_con = -1;
- } else if (WIFSIGNALED(w)) {
- e = WTERMSIG(w) + 128;
- pid_con = -1;
- }
- }
- }
-
- if (e == 0)
- e = e2;
- exit(e);
-}
-
-/*
- * Wait for monitoring to synchronise.
- */
-void act_keyctl_watch_sync(int argc, char *argv[])
-{
- struct watch_queue_buffer *buf;
- //unsigned int head, tail;
- size_t page_size;
- int wfd;
-
- if (argc != 2)
- format();
-
- wfd = atoi(argv[1]);
-
- /* We only need to see the first page. */
- page_size = sysconf(_SC_PAGESIZE);
- buf = mmap(NULL, 1 * page_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, wfd, 0);
- if (buf == MAP_FAILED)
- error("mmap");
-
-#if 0
- head = __atomic_load_n(&buf->meta.head, __ATOMIC_RELAXED);
-
- while (tail = __atomic_load_n(&buf->meta.tail, __ATOMIC_RELAXED),
- !after_eq(tail, head)
- )
- usleep(10000);
-#endif
- exit(0);
-}
diff --git a/keyutils.c b/keyutils.c
index 48b779e..9877fdb 100644
--- a/keyutils.c
+++ b/keyutils.c
@@ -385,11 +385,6 @@ long keyctl_capabilities(unsigned char *buffer, size_t buflen)
return sizeof(unsigned char);
}
-long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id)
-{
- return keyctl(KEYCTL_WATCH_KEY, id, watch_queue_fd, watch_id);
-}
-
/*****************************************************************************/
/*
* fetch key description into an allocated buffer
diff --git a/keyutils.h b/keyutils.h
index 3f672bc..4ae81d3 100644
--- a/keyutils.h
+++ b/keyutils.h
@@ -112,7 +112,6 @@ typedef uint32_t key_perm_t;
#define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */
#define KEYCTL_MOVE 30 /* Move keys between keyrings */
#define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */
-#define KEYCTL_WATCH_KEY 32 /* Watch a key or ring of keys for changes */
/* keyctl structures */
struct keyctl_dh_params {
@@ -169,7 +168,6 @@ struct keyctl_pkey_params {
#define KEYCTL_CAPS0_MOVE 0x80 /* KEYCTL_MOVE supported */
#define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01 /* Keyring names are per-user_namespace */
#define KEYCTL_CAPS1_NS_KEY_TAG 0x02 /* Key indexing can include a namespace tag */
-#define KEYCTL_CAPS1_NOTIFICATIONS 0x04 /* Keys generate watchable notifications */
/*
* syscall wrappers
@@ -257,7 +255,6 @@ extern long keyctl_move(key_serial_t id,
key_serial_t to_ringid,
unsigned int flags);
extern long keyctl_capabilities(unsigned char *buffer, size_t buflen);
-extern long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id);
/*
* utilities
diff --git a/man/keyctl.1 b/man/keyctl.1
index f18f92d..2f545bd 100644
--- a/man/keyctl.1
+++ b/man/keyctl.1
@@ -114,15 +114,6 @@ keyctl \- key management facility control
\fBkeyctl\fR pkey_sign <key> <pass> <datafile> [k=v]* ><sigfile>
.br
\fBkeyctl\fR pkey_decrypt <key> <pass> <datafile> <sigfile> [k=v]*
-.br
-\fBkeyctl\fR watch <key>
-.br
-\fBkeyctl\fR watch_add <fd> <key>
-.br
-\fBkeyctl\fR watch_rm <fd> <key>
-.br
-\fBkeyctl\fR watch_session [-n <name>] \\
- <notifylog> <gclog> <fd> <prog> [<arg1> <arg2> ...]
.SH DESCRIPTION
This program is used to control the key management facility in various ways
using a variety of subcommands.
@@ -953,89 +944,6 @@ keyctl pkey_verify $k 0 foo.hash foo.sig enc=pkcs1 hash=sha256
.PP
See asymmetric-key(7) for more information.
-.SS Change notifications
-\fBkeyctl\fR watch <key>
-.br
-\fBkeyctl\fR watch_session [-n <name>] \\
- <notifylog> <gclog> <fd> <prog> [<arg1> <arg2> ...]
-\fBkeyctl\fR watch_add <fd> <key>
-.br
-\fBkeyctl\fR watch_rm <fd> <key>
-.br
-.PP
-The
-.B watch
-command watches a single key, printing notifications to stdout until the key
-is destroyed.
-.PP
-The output of the command looks like:
-.PP
-.RS
-.nf
-.RI < keyid "> <" event "> [<" aux ">]"
-.fi
-.RE
-.PP
-Where
-.I keyid
-is the primary subject of the notification,
-.I op
-is the event and
-.I aux
-is the secondary key if there is one (such as link where the primary key is
-the keyring secondary key is the key being linked in to it). For example:
-.PP
-.RS
-.nf
-255913279 link 340681059
-255913279 clr
-.fi
-.RE
-.PP
-An additional notication is generated when a key being watched is garbage
-collected, e.g.:
-.PP
-.RS
-.nf
-255913279 gc
-.fi
-.RE
-.PP
-The
-.B watch_session
-command creates a new session keyring, with name
-.I name
-if given, watches it for notifications and runs program
-.I prog
-with it. The program is given the specified arguments.
-.PP
-A second process is forked off to monitor the notifications. The output from
-that is directed to the files
-.I notifylog
-for most notifications and
-.I gclog
-for key removal notifications (which are asynchronous and may be deferred).
-.PP
-The
-.BR watch_queue (7)
-device is exported to the program attached to fd number
-.IR fd .
-This can be passed by the other two commands.
-.PP
-The
-.B watch_add
-command adds a watch on
-.I key
-to the
-.B watch_queue
-attached to
-.I fd
-as exported by watch_session and the
-.B watch_rm
-caommand removes it. A watch_queue can handle multiple keys and even non-keys
-sources as well.
-
-
.SH ERRORS
There are a number of common errors returned by this program:
diff --git a/man/keyctl.3 b/man/keyctl.3
index fda0363..cb0449c 100644
--- a/man/keyctl.3
+++ b/man/keyctl.3
@@ -104,8 +104,6 @@ and then telling the linker it should link in the library:
.BR keyctl_unlink (3)
.br
.BR keyctl_update (3)
-.br
-.BR keyctl_watch_key (3)
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.SH UTILITY FUNCTIONS
.BR find_key_by_type_and_name (3)
diff --git a/man/keyctl_watch_key.3 b/man/keyctl_watch_key.3
deleted file mode 100644
index 044b7a3..0000000
--- a/man/keyctl_watch_key.3
+++ /dev/null
@@ -1,206 +0,0 @@
-.\"
-.\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
-.\" Written by David Howells (dhowells@redhat.com)
-.\"
-.\" This program is free software; you can redistribute it and/or
-.\" modify it under the terms of the GNU General Public License
-.\" as published by the Free Software Foundation; either version
-.\" 2 of the License, or (at your option) any later version.
-.\"
-.TH KEYCTL_GRANT_PERMISSION 3 "28 Aug 2019" Linux "Linux Key Management Calls"
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SH NAME
-keyctl_watch_key \- Watch for changes to a key
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SH SYNOPSIS
-.nf
-.B #include <keyutils.h>
-.sp
-.BI "long keyctl_watch_key(key_serial_t " key ,
-.BI " int " watch_queue_fd
-.BI " int " watch_id ");"
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SH DESCRIPTION
-.BR keyctl_watch_key ()
-sets or removes a watch on
-.IR key .
-.PP
-.I watch_id
-specifies the ID for a watch that will be included in notification messages.
-It can be between 0 and 255 to add a key; it should be -1 to remove a key.
-.PP
-.I watch_queue_fd
-is a file descriptor attached to a watch_queue device instance. Multiple
-openings of a device provide separate instances. Each device instance can
-only have one watch on any particular key.
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SS Notification Record
-.PP
-Key-specific notification messages that the kernel emits into the buffer have
-the following format:
-.PP
-.in +4n
-.EX
-struct key_notification {
- struct watch_notification watch;
- __u32 key_id;
- __u32 aux;
-};
-.EE
-.in
-.PP
-The
-.I watch.type
-field will be set to
-.B WATCH_TYPE_KEY_NOTIFY
-and the
-.I watch.subtype
-field will contain one of the following constants, indicating the event that
-occurred and the watch_id passed to keyctl_watch_key() will be placed in
-.I watch.info
-in the ID field. The following events are defined:
-.TP
-.B NOTIFY_KEY_INSTANTIATED
-This indicates that a watched key got instantiated or negatively instantiated.
-.I key_id
-indicates the key that was instantiated and
-.I aux
-is unused.
-.TP
-.B NOTIFY_KEY_UPDATED
-This indicates that a watched key got updated or instantiated by update.
-.I key_id
-indicates the key that was updated and
-.I aux
-is unused.
-.TP
-.B NOTIFY_KEY_LINKED
-This indicates that a key got linked into a watched keyring.
-.I key_id
-indicates the keyring that was modified
-.I aux
-indicates the key that was added.
-.TP
-.B NOTIFY_KEY_UNLINKED
-This indicates that a key got unlinked from a watched keyring.
-.I key_id
-indicates the keyring that was modified
-.I aux
-indicates the key that was removed.
-.TP
-.B NOTIFY_KEY_CLEARED
-This indicates that a watched keyring got cleared.
-.I key_id
-indicates the keyring that was cleared and
-.I aux
-is unused.
-.TP
-.B NOTIFY_KEY_REVOKED
-This indicates that a watched key got revoked.
-.I key_id
-indicates the key that was revoked and
-.I aux
-is unused.
-.TP
-.B NOTIFY_KEY_INVALIDATED
-This indicates that a watched key got invalidated.
-.I key_id
-indicates the key that was invalidated and
-.I aux
-is unused.
-.TP
-.B NOTIFY_KEY_SETATTR
-This indicates that a watched key had its attributes (owner, group,
-permissions, timeout) modified.
-.I key_id
-indicates the key that was modified and
-.I aux
-is unused.
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SS Removal Notification
-When a watched key is garbage collected, all of its watches are automatically
-destroyed and a notification is delivered to each watcher. This will normally
-be an extended notification of the form:
-.PP
-.in +4n
-.EX
-struct watch_notification_removal {
- struct watch_notification watch;
- __u64 id;
-};
-.EE
-.in
-.PP
-The
-.I watch.type
-field will be set to
-.B WATCH_TYPE_META
-and the
-.I watch.subtype
-field will contain
-.BR WATCH_META_REMOVAL_NOTIFICATION .
-If the extended notification is given, then the length will be 2 units,
-otherwise it will be 1 and only the header will be present.
-.PP
-The watch_id passed to
-.IR keyctl_watch_key ()
-will be placed in
-.I watch.info
-in the ID field.
-.PP
-If the extension is present,
-.I id
-will be set to the ID of the destroyed key.
-.PP
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SH RETURN VALUE
-On success
-.BR keyctl_watch_key ()
-returns
-.B 0 .
-On error, the value
-.B -1
-will be returned and
-.I errno
-will have been set to an appropriate error.
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SH ERRORS
-.TP
-.B ENOKEY
-The specified key does not exist.
-.TP
-.B EKEYEXPIRED
-The specified key has expired.
-.TP
-.B EKEYREVOKED
-The specified key has been revoked.
-.TP
-.B EACCES
-The named key exists, but does not grant
-.B view
-permission to the calling process.
-.TP
-.B EBUSY
-The specified key already has a watch on it for that device instance (add
-only).
-.TP
-.B EBADSLT
-The specified key doesn't have a watch on it (removal only).
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SH LINKING
-This is a library function that can be found in
-.IR libkeyutils .
-When linking,
-.B \-lkeyutils
-should be specified to the linker.
-.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
-.SH SEE ALSO
-.ad l
-.nh
-.BR keyctl (1),
-.BR add_key (2),
-.BR keyctl (2),
-.BR request_key (2),
-.BR keyctl (3),
-.BR keyrings (7),
-.BR keyutils (7)
diff --git a/tests/prepare.inc.sh b/tests/prepare.inc.sh
index a306ed0..448e42b 100644
--- a/tests/prepare.inc.sh
+++ b/tests/prepare.inc.sh
@@ -74,7 +74,6 @@ have_key_invalidate=0
have_big_key_type=0
have_dh_compute=0
have_restrict_keyring=0
-have_notify=0
if keyctl supports capabilities >&/dev/null
then
diff --git a/version.lds b/version.lds
index 6c34adf..2a6e142 100644
--- a/version.lds
+++ b/version.lds
@@ -100,7 +100,5 @@ KEYUTILS_1.9 {
} KEYUTILS_1.8;
KEYUTILS_1.10 {
- /* Management functions */
- keyctl_watch_key;
} KEYUTILS_1.9;
diff --git a/watch_queue.h b/watch_queue.h
deleted file mode 100644
index 16883d7..0000000
--- a/watch_queue.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _KEYUTILS_LINUX_WATCH_QUEUE_H
-#define _KEYUTILS_LINUX_WATCH_QUEUE_H
-
-#include <linux/types.h>
-#include <sys/ioctl.h>
-
-#define IOC_WATCH_QUEUE_SET_SIZE _IO('W', 0x60) /* Set the size in pages */
-#define IOC_WATCH_QUEUE_SET_FILTER _IO('W', 0x61) /* Set the filter */
-
-enum watch_notification_type {
- WATCH_TYPE_META = 0, /* Special record */
- WATCH_TYPE_KEY_NOTIFY = 1, /* Key change event notification */
- WATCH_TYPE___NR = 2
-};
-
-enum watch_meta_notification_subtype {
- WATCH_META_SKIP_NOTIFICATION = 0, /* Just skip this record */
- WATCH_META_REMOVAL_NOTIFICATION = 1, /* Watched object was removed */
-};
-
-#define WATCH_LENGTH_GRANULARITY sizeof(__u64)
-
-/*
- * Notification record header. This is aligned to 64-bits so that subclasses
- * can contain __u64 fields.
- */
-struct watch_notification {
- __u32 type:24; /* enum watch_notification_type */
- __u32 subtype:8; /* Type-specific subtype (filterable) */
- __u32 info;
-#define WATCH_INFO_LENGTH 0x0000003f /* Length of record / sizeof(watch_notification) */
-#define WATCH_INFO_LENGTH__SHIFT 0
-#define WATCH_INFO_ID 0x0000ff00 /* ID of watchpoint, if type-appropriate */
-#define WATCH_INFO_ID__SHIFT 8
-#define WATCH_INFO_TYPE_INFO 0xffff0000 /* Type-specific info */
-#define WATCH_INFO_TYPE_INFO__SHIFT 16
-#define WATCH_INFO_FLAG_0 0x00010000 /* Type-specific info, flag bit 0 */
-#define WATCH_INFO_FLAG_1 0x00020000 /* ... */
-#define WATCH_INFO_FLAG_2 0x00040000
-#define WATCH_INFO_FLAG_3 0x00080000
-#define WATCH_INFO_FLAG_4 0x00100000
-#define WATCH_INFO_FLAG_5 0x00200000
-#define WATCH_INFO_FLAG_6 0x00400000
-#define WATCH_INFO_FLAG_7 0x00800000
-} __attribute__((aligned(WATCH_LENGTH_GRANULARITY)));
-
-struct watch_queue_buffer {
- union {
- /* The first few entries are special, containing the
- * ring management variables.
- */
- struct {
- struct watch_notification watch; /* WATCH_TYPE_META */
- __u32 head; /* Ring head index */
- __u32 tail; /* Ring tail index */
- __u32 mask; /* Ring index mask */
- __u32 __reserved;
- } meta;
- struct watch_notification slots[0];
- };
-};
-
-/*
- * The Metadata pseudo-notification message uses a flag bits in the information
- * field to convey the fact that messages have been lost. We can only use a
- * single bit in this manner per word as some arches that support SMP
- * (eg. parisc) have no kernel<->user atomic bit ops.
- */
-#define WATCH_INFO_NOTIFICATIONS_LOST WATCH_INFO_FLAG_0
-
-/*
- * Notification filtering rules (IOC_WATCH_QUEUE_SET_FILTER).
- */
-struct watch_notification_type_filter {
- __u32 type; /* Type to apply filter to */
- __u32 info_filter; /* Filter on watch_notification::info */
- __u32 info_mask; /* Mask of relevant bits in info_filter */
- __u32 subtype_filter[8]; /* Bitmask of subtypes to filter on */
-};
-
-struct watch_notification_filter {
- __u32 nr_filters; /* Number of filters */
- __u32 __reserved; /* Must be 0 */
- struct watch_notification_type_filter filters[];
-};
-
-
-/*
- * Extended watch removal notification. This is used optionally if the type
- * wants to indicate an identifier for the object being watched, if there is
- * such. This can be distinguished by the length.
- *
- * type -> WATCH_TYPE_META
- * subtype -> WATCH_META_REMOVAL_NOTIFICATION
- * length -> 2 * gran
- */
-struct watch_notification_removal {
- struct watch_notification watch;
- __u64 id; /* Type-dependent identifier */
-};
-
-/*
- * Type of key/keyring change notification.
- */
-enum key_notification_subtype {
- NOTIFY_KEY_INSTANTIATED = 0, /* Key was instantiated (aux is error code) */
- NOTIFY_KEY_UPDATED = 1, /* Key was updated */
- NOTIFY_KEY_LINKED = 2, /* Key (aux) was added to watched keyring */
- NOTIFY_KEY_UNLINKED = 3, /* Key (aux) was removed from watched keyring */
- NOTIFY_KEY_CLEARED = 4, /* Keyring was cleared */
- NOTIFY_KEY_REVOKED = 5, /* Key was revoked */
- NOTIFY_KEY_INVALIDATED = 6, /* Key was invalidated */
- NOTIFY_KEY_SETATTR = 7, /* Key's attributes got changed */
-};
-
-/*
- * Key/keyring notification record.
- * - watch.type = WATCH_TYPE_KEY_NOTIFY
- * - watch.subtype = enum key_notification_type
- */
-struct key_notification {
- struct watch_notification watch;
- __u32 key_id; /* The key/keyring affected */
- __u32 aux; /* Per-type auxiliary data */
-};
-
-#endif /* _KEYUTILS_LINUX_WATCH_QUEUE_H */