diff options
author | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-08-02 18:04:28 +0000 |
---|---|---|
committer | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-08-02 18:04:28 +0000 |
commit | b7f49181c916f27256935b8bef244cfbb590d913 (patch) | |
tree | 50f748330ddc94966919a2f4c5ab1641460bb2ce /tools/xenstore/xenstored_watch.c | |
parent | 0603c5d12a19452e6bcea047511b0ea32d30eef0 (diff) | |
download | xen-b7f49181c916f27256935b8bef244cfbb590d913.tar.gz xen-b7f49181c916f27256935b8bef244cfbb590d913.tar.bz2 xen-b7f49181c916f27256935b8bef244cfbb590d913.zip |
Implement watching of nodes which don't exist.
Requires permission check every time event is generated.
Requires generalization of permissions: ask arbitrary number of
parents whether it's OK to tell about node (eg. watching
/dir/subdir/x when /dir is deleted: root permissions will now
determine whether we fire event).
Add test that we don't leak information on whether a file exists
or not.
Signed-off-by: Rusty Russel <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Diffstat (limited to 'tools/xenstore/xenstored_watch.c')
-rw-r--r-- | tools/xenstore/xenstored_watch.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index 1c42b72ced..a2727e46e4 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -95,10 +95,19 @@ static int destroy_watch_event(void *_event) return 0; } -static void add_event(struct watch *watch, const char *node) +static void add_event(struct connection *conn, + struct watch *watch, const char *node) { struct watch_event *event; + /* Check read permission: no permission, no watch event. + * If it doesn't exist, we need permission to read parent. + */ + if (!check_node_perms(conn, node, XS_PERM_READ|XS_PERM_ENOENT_OK)) { + fprintf(stderr, "No permission for %s\n", node); + return; + } + if (watch->relative_path) { node += strlen(watch->relative_path); if (*node == '/') /* Could be "" */ @@ -132,9 +141,9 @@ void fire_watches(struct connection *conn, const char *node, bool recurse) list_for_each_entry(watch, &i->watches, list) { if (is_child(node, watch->node)) - add_event(watch, node); + add_event(i, watch, node); else if (recurse && is_child(watch->node, node)) - add_event(watch, watch->node); + add_event(i, watch, watch->node); else continue; /* If connection not doing anything, queue this. */ @@ -206,7 +215,7 @@ void do_watch(struct connection *conn, struct buffered_data *in) relative = !strstarts(vec[0], "/"); vec[0] = canonicalize(conn, vec[0]); - if (!check_node_perms(conn, vec[0], XS_PERM_READ)) { + if (!is_valid_nodename(vec[0])) { send_error(conn, errno); return; } |