aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/xenstored_watch.c
diff options
context:
space:
mode:
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2005-08-02 18:04:28 +0000
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2005-08-02 18:04:28 +0000
commitb7f49181c916f27256935b8bef244cfbb590d913 (patch)
tree50f748330ddc94966919a2f4c5ab1641460bb2ce /tools/xenstore/xenstored_watch.c
parent0603c5d12a19452e6bcea047511b0ea32d30eef0 (diff)
downloadxen-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.c17
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;
}