let fire_single_watch (oldroot, root) watch =
let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
let perms = lookup_watch_perms oldroot root abspath in
- if List.exists (Perms.has watch.con.perm READ) perms then
+ if Perms.can_fire_watch watch.con.perm perms then
fire_single_watch_unchecked watch
else
let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
# Activate node permission system
perms-activate = true
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
# Activate quota
quota-activate = true
quota-maxentity = 1000
open Stdext
let activate = ref true
+let watch_activate = ref true
type permty = READ | WRITE | RDWR | NONE
(* check if the current connection has the requested perm on the current node *)
let has connection request node = not (lacks connection request node)
+let can_fire_watch connection perms =
+ not !watch_activate
+ || List.exists (has connection READ) perms
+
let equiv perm1 perm2 =
(Node.to_string perm1) = (Node.to_string perm2)
("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
("perms-activate", Config.Set_bool Perms.activate);
+ ("perms-watch-activate", Config.Set_bool Perms.watch_activate);
("quota-activate", Config.Set_bool Quota.activate);
("quota-maxwatch", Config.Set_int Define.maxwatch);
("quota-transaction", Config.Set_int Define.maxtransaction);