# Allow fh-backup-restore to stop and start futurehome services
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl start kind-owl.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl stop kind-owl.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl start zigbee-ad.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl stop zigbee-ad.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl start ecollector.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl stop ecollector.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl start tpflow.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl stop tpflow.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl start energy-guard.service
%fh-backup-restore ALL=NOPASSWD: /bin/systemctl stop energy-guard.service
%fh-backup-restore ALL=NOPASSWD: /usr/bin/svc -d /etc/service/zwave-ad
%fh-backup-restore ALL=NOPASSWD: /usr/bin/svc -u /etc/service/zwave-ad
%fh-backup-restore ALL=NOPASSWD: /usr/bin/svc -d /etc/service/zipgateway
%fh-backup-restore ALL=NOPASSWD: /usr/bin/svc -u /etc/service/zipgateway
%fh-backup-restore ALL=NOPASSWD: /usr/bin/svc -t /etc/service/hyperchannel

# NVM (700-series via zgw_*; 500-series via fh-zw-flash)
%fh-backup-restore ALL=NOPASSWD: /usr/local/bin/zgw_backup.sh -b /var/lib/futurehome/backup-restore/backup/nvm2.zip
%fh-backup-restore ALL=NOPASSWD: /usr/local/bin/zgw_recover.sh -b /var/lib/futurehome/backup-restore/backup/nvm2.zip
%fh-backup-restore ALL=NOPASSWD: /usr/local/bin/zgw_backup.sh -b /var/lib/futurehome/backup-restore/snapshot/nvm2.zip
%fh-backup-restore ALL=NOPASSWD: /usr/local/bin/zgw_recover.sh -b /var/lib/futurehome/backup-restore/snapshot/nvm2.zip
%fh-backup-restore ALL=NOPASSWD: /usr/bin/fh-zw-flash --backup-nvm /var/lib/futurehome/backup-restore/backup/nvm.bin -- /dev/futurehome/Z-Wave
%fh-backup-restore ALL=NOPASSWD: /usr/bin/fh-zw-flash --backup-nvm /var/lib/futurehome/backup-restore/snapshot/nvm.bin -- /dev/futurehome/Z-Wave
%fh-backup-restore ALL=NOPASSWD: /usr/bin/fh-zw-flash --restore-nvm /var/lib/futurehome/backup-restore/backup/nvm.bin -- /dev/futurehome/Z-Wave
%fh-backup-restore ALL=NOPASSWD: /usr/bin/fh-zw-flash --restore-nvm /var/lib/futurehome/backup-restore/snapshot/nvm.bin -- /dev/futurehome/Z-Wave

# File restore (restore.sh -> sudo cp)
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_zwave_device_rec.txt /var/lib/futurehome/zwave-ad/zwave_device_rec.txt
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_zwave_device_rec.txt /var/lib/futurehome/zwave-ad/zwave_device_rec.txt
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_newly_added_devices.json /var/lib/futurehome/zwave-ad/newly_added_devices.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_newly_added_devices.json /var/lib/futurehome/zwave-ad/newly_added_devices.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_polling_info.json /var/lib/futurehome/zwave-ad/polling_info.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_polling_info.json /var/lib/futurehome/zwave-ad/polling_info.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_user_code.json /var/lib/futurehome/zwave-ad/user_code.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_user_code.json /var/lib/futurehome/zwave-ad/user_code.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_device_blocklist.json /var/lib/futurehome/zwave-ad/device_blocklist.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_device_blocklist.json /var/lib/futurehome/zwave-ad/device_blocklist.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_device_priority.json /var/lib/futurehome/zwave-ad/device_priority.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_device_priority.json /var/lib/futurehome/zwave-ad/device_priority.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_zware_network.jsn /var/lib/futurehome/zwave-ad/zware_network.jsn
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_zware_network.jsn /var/lib/futurehome/zwave-ad/zware_network.jsn
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zwave-ad_zware_net.json /var/lib/futurehome/zwave-ad/zware_net.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zwave-ad_zware_net.json /var/lib/futurehome/zwave-ad/zware_net.json
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zipgateway_zipgateway_provisioning_list.cfg /usr/local/etc/zipgateway_provisioning_list.cfg
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zipgateway_zipgateway_provisioning_list.cfg /usr/local/etc/zipgateway_provisioning_list.cfg
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zipgateway_eeprom.dat /usr/local/var/lib/zipgateway/eeprom.dat
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zipgateway_eeprom.dat /usr/local/var/lib/zipgateway/eeprom.dat
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/zipgateway_zipgateway.db /usr/local/var/lib/zipgateway/zipgateway.db
%fh-backup-restore ALL=NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/zipgateway_zipgateway.db /usr/local/var/lib/zipgateway/zipgateway.db
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/zwave_device_rec.txt
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /usr/local/var/lib/zipgateway/eeprom.dat
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /usr/local/var/lib/zipgateway/zipgateway.db
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/zware_network.jsn
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/zware_net.json
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/newly_added_devices.json
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/polling_info.json
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/user_code.json
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/device_blocklist.json
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zwave-ad/device_priority.json
%fh-backup-restore ALL=NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /usr/local/etc/zipgateway_provisioning_list.cfg

%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/zwave_device_rec.txt
%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/zware_network.jsn
%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/zware_net.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/newly_added_devices.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/polling_info.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/user_code.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/device_blocklist.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown zwave-ad\:zwave-ad /var/lib/futurehome/zwave-ad/device_priority.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown root\:root /usr/local/etc/zipgateway_provisioning_list.cfg
%fh-backup-restore ALL=NOPASSWD: /bin/chown root\:root /usr/local/var/lib/zipgateway/eeprom.dat
%fh-backup-restore ALL=NOPASSWD: /bin/chown zipgateway\:zipgateway /usr/local/var/lib/zipgateway/eeprom.dat
%fh-backup-restore ALL=NOPASSWD: /bin/chown root\:root /usr/local/var/lib/zipgateway/zipgateway.db
%fh-backup-restore ALL=NOPASSWD: /bin/chown zipgateway\:zipgateway /usr/local/var/lib/zipgateway/zipgateway.db

# Directory apps: stage with sudo zip to .tmp then rename (avoids symlink TOCTOU
# on the final path), restore via the binary's --extract subcommand.
#
# No rule that writes inside an app's own tree runs as root - see the
# (zigbee-ad) / (tpflow) runas specs. The app already owns the destination, so
# root buys nothing and costs a root-write primitive aimed at paths a compromised
# fh-backup-restore names; the worst a bug or a hostile archive reaches is data
# that account already owns and is about to have replaced anyway. Extracting under
# the app's uid is also what removes the ownership handback: the files are created
# correct rather than chowned afterwards. The staging `zip` rules below stay root
# because they read the app's data, which fh-backup-restore cannot.
#
# -y is not optional on those rules. zip follows a symlink by default and stores
# the file it points at, so without it a root `zip` over a tree the app owns is an
# arbitrary root read: a link planted in flow_storage/ lands /etc/shadow in the
# archive, which is then chowned back to this user and uploaded. sudoers cannot
# constrain the working directory, so `backups` need not even be the app's - any
# directory this user can write, with `backups` a link to /root, matches the rule
# as written. -y stores links as links, and ValidateArchive already refuses those
# at restore, so the attempt fails loudly instead of succeeding quietly.
#
# Still not raw `unzip -o`: a caller that already controls fh-backup-restore could
# invoke the rule directly on an archive it staged, and unzip materializes a
# symlink member then writes through it. --extract re-runs ValidateArchive on the
# privileged side, against the same inode it extracts, and writes with a Go reader
# that never creates or follows symlinks.
%fh-backup-restore ALL=NOPASSWD: /usr/bin/zip -r -q -y /var/lib/futurehome/backup-restore/backup/zigbee-ad_backups.zip.tmp backups
%fh-backup-restore ALL=NOPASSWD: /usr/bin/zip -r -q -y /var/lib/futurehome/backup-restore/snapshot/zigbee-ad_backups.zip.tmp backups
%fh-backup-restore ALL=NOPASSWD: /usr/bin/zip -r -q -y /var/lib/futurehome/backup-restore/backup/tpflow_flow_storage.zip.tmp flow_storage
%fh-backup-restore ALL=NOPASSWD: /usr/bin/zip -r -q -y /var/lib/futurehome/backup-restore/snapshot/tpflow_flow_storage.zip.tmp flow_storage
%fh-backup-restore ALL=(zigbee-ad) NOPASSWD: /usr/bin/backup-restore --extract /var/lib/futurehome/backup-restore/backup/zigbee-ad_backups.zip /var/lib/futurehome/zigbee-ad backups
%fh-backup-restore ALL=(zigbee-ad) NOPASSWD: /usr/bin/backup-restore --extract /var/lib/futurehome/backup-restore/snapshot/zigbee-ad_backups.zip /var/lib/futurehome/zigbee-ad backups
%fh-backup-restore ALL=(tpflow) NOPASSWD: /usr/bin/backup-restore --extract /var/lib/futurehome/backup-restore/backup/tpflow_flow_storage.zip /var/lib/futurehome/tpflow/var flow_storage
%fh-backup-restore ALL=(tpflow) NOPASSWD: /usr/bin/backup-restore --extract /var/lib/futurehome/backup-restore/snapshot/tpflow_flow_storage.zip /var/lib/futurehome/tpflow/var flow_storage
%fh-backup-restore ALL=(tpflow) NOPASSWD: /usr/bin/backup-restore --extract /var/lib/futurehome/backup-restore/backup/tpflow_flow_storage.zip /opt/thingsplex/tpflow/var flow_storage
%fh-backup-restore ALL=(tpflow) NOPASSWD: /usr/bin/backup-restore --extract /var/lib/futurehome/backup-restore/snapshot/tpflow_flow_storage.zip /opt/thingsplex/tpflow/var flow_storage
%fh-backup-restore ALL=(zigbee-ad) NOPASSWD: /bin/rm -rf /var/lib/futurehome/zigbee-ad/backups.old
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/rm -rf /var/lib/futurehome/tpflow/var/flow_storage.old
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/rm -rf /opt/thingsplex/tpflow/var/flow_storage.old
%fh-backup-restore ALL=(zigbee-ad) NOPASSWD: /bin/mv /var/lib/futurehome/zigbee-ad/backups /var/lib/futurehome/zigbee-ad/backups.old
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/mv /var/lib/futurehome/tpflow/var/flow_storage /var/lib/futurehome/tpflow/var/flow_storage.old
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/mv /opt/thingsplex/tpflow/var/flow_storage /opt/thingsplex/tpflow/var/flow_storage.old

# Replaying app_file.info on a directory app. Modes are matched by character
# class, never `*`: sudo matches arguments as one concatenated string, so `[0-7]`
# stays inside its argument while `chown -R tpflow\:*` would also match
# `-R tpflow\:x /etc/shadow <path>`. SanitizeMode clears other-write before the
# mode gets here.
%fh-backup-restore ALL=(zigbee-ad) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/zigbee-ad/backups
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/tpflow/var/flow_storage
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /opt/thingsplex/tpflow/var/flow_storage
# The extraction already lands the tree under the app's own account and primary
# group, so on a same-layout restore PermOwnerModeMatch finds it correct and none
# of these run. They are here for an archive from a hub whose group differs.
# Enumerated, so a group the archive invents is refused rather than set; and as
# the app rather than root, so the only groups reachable are ones it belongs to.
%fh-backup-restore ALL=(zigbee-ad) NOPASSWD: /bin/chown -R zigbee-ad\:thingsplex /var/lib/futurehome/zigbee-ad/backups
%fh-backup-restore ALL=(zigbee-ad) NOPASSWD: /bin/chown -R zigbee-ad\:futurehome /var/lib/futurehome/zigbee-ad/backups
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/chown -R tpflow\:thingsplex /var/lib/futurehome/tpflow/var/flow_storage
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/chown -R tpflow\:futurehome /var/lib/futurehome/tpflow/var/flow_storage
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/chown -R tpflow\:thingsplex /opt/thingsplex/tpflow/var/flow_storage
%fh-backup-restore ALL=(tpflow) NOPASSWD: /bin/chown -R tpflow\:futurehome /opt/thingsplex/tpflow/var/flow_storage
# Same for the single-file apps, and as the app for the same reason: root would be
# changing the group of a file inside a directory that account owns.
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:thingsplex /var/lib/futurehome/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:futurehome /var/lib/futurehome/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:thingsplex /var/lib/futurehome/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:futurehome /var/lib/futurehome/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:thingsplex /opt/thingsplex/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:futurehome /opt/thingsplex/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:thingsplex /opt/thingsplex/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\:futurehome /opt/thingsplex/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\:thingsplex /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\:futurehome /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\:thingsplex /opt/thingsplex/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\:futurehome /opt/thingsplex/kind-owl/config.json
# kindowl's primary group is kindowl, not futurehome: its postinst creates the
# account with --ingroup kindowl and only adds futurehome as a secondary. That is
# the pair PrimaryGroupFor resolves to on every hub, so it is the one a restore
# actually asks for.
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\:kindowl /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\:kindowl /opt/thingsplex/kind-owl/config.json
# energy-guard has no thingsplex ancestry and no group of its own: postinst puts
# the account in futurehome, so that is the only group an archive can name here.
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/chown energy-guard\:futurehome /var/lib/futurehome/energy-guard/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/chown energy-guard\:futurehome /var/lib/futurehome/energy-guard/data.db

# After sudo zip into staging, reclaim ownership so checksum/zip can read the files.
# -h = no-dereference, so a symlink planted at the staging path is retargeted
# rather than followed. No privileged chmod belongs here at all, wildcard or not:
# chmod has no -h, this user owns the staging directory, and a rule naming one
# exact path is still `ln -s /etc/shadow <that path>` away from handing out any
# root-owned file on the hub. claimStaged chmods as itself once it owns the file.
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h fh-backup-restore\:fh-backup-restore /var/lib/futurehome/backup-restore/backup/zigbee-ad_backups.zip
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h fh-backup-restore\:fh-backup-restore /var/lib/futurehome/backup-restore/backup/tpflow_flow_storage.zip
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h fh-backup-restore\:fh-backup-restore /var/lib/futurehome/backup-restore/snapshot/zigbee-ad_backups.zip
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h fh-backup-restore\:fh-backup-restore /var/lib/futurehome/backup-restore/snapshot/tpflow_flow_storage.zip

# Restricted single-file apps: cat into staging, restore via cp. Every rule below
# runs as the owning account, none as root, for the same reason the directory apps
# do: the source and the destination both belong to that app already.
#
# The reads matter as much as the writes here. cat has no no-dereference form, and
# these paths sit in directories the app owns, so a root `cat` cannot be made safe
# by checking the path first - the app replaces it with a link to a root-only file
# between the check and the read, and the privileged read follows it into the
# archive that gets uploaded. There is no ordering that fixes that; only dropping
# the privilege does, and then the swap gains the app nothing it did not have.
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cat /var/lib/futurehome/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cat /var/lib/futurehome/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cat /opt/thingsplex/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cat /opt/thingsplex/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/cat /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/cat /opt/thingsplex/kind-owl/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/cat /var/lib/futurehome/energy-guard/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/cat /var/lib/futurehome/energy-guard/data.db
# The same argument on the write side: RefuseSymlinkInPath runs before the copy,
# but the app owns the destination and can replace it afterwards, so as root the
# copy would write through the link. As the app it resolves to a file the app is
# no more able to write than it was already.
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/ecollector_config.json /var/lib/futurehome/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/ecollector_config.json /var/lib/futurehome/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/ecollector_influxdb.json /var/lib/futurehome/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/ecollector_influxdb.json /var/lib/futurehome/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/ecollector_config.json /opt/thingsplex/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/ecollector_config.json /opt/thingsplex/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/ecollector_influxdb.json /opt/thingsplex/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/ecollector_influxdb.json /opt/thingsplex/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/kind-owl_config.json /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/kind-owl_config.json /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/kind-owl_config.json /opt/thingsplex/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/kind-owl_config.json /opt/thingsplex/kind-owl/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/energy-guard_config.json /var/lib/futurehome/energy-guard/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/energy-guard_config.json /var/lib/futurehome/energy-guard/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/backup/energy-guard_data.db /var/lib/futurehome/energy-guard/data.db
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/cp /var/lib/futurehome/backup-restore/snapshot/energy-guard_data.db /var/lib/futurehome/energy-guard/data.db
# The app has to be able to read the staged file for that copy, and it is owned by
# fh-backup-restore at 0600. Hand it over rather than widening it: the staging
# directory is world-traversable, and ecollector's influxdb.json carries influx
# credentials that would otherwise be readable by every account on the hub for the
# length of a restore. Root only for the ownership change, exact path, and -h so a
# symlink planted at the staging path is retargeted instead of followed - the same
# form as the reclaim rules above, in the other direction.
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h ecollector\: /var/lib/futurehome/backup-restore/backup/ecollector_config.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h ecollector\: /var/lib/futurehome/backup-restore/snapshot/ecollector_config.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h ecollector\: /var/lib/futurehome/backup-restore/backup/ecollector_influxdb.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h ecollector\: /var/lib/futurehome/backup-restore/snapshot/ecollector_influxdb.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h kindowl\: /var/lib/futurehome/backup-restore/backup/kind-owl_config.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h kindowl\: /var/lib/futurehome/backup-restore/snapshot/kind-owl_config.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h energy-guard\: /var/lib/futurehome/backup-restore/backup/energy-guard_config.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h energy-guard\: /var/lib/futurehome/backup-restore/snapshot/energy-guard_config.json
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h energy-guard\: /var/lib/futurehome/backup-restore/backup/energy-guard_data.db
%fh-backup-restore ALL=NOPASSWD: /bin/chown -h energy-guard\: /var/lib/futurehome/backup-restore/snapshot/energy-guard_data.db
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\: /var/lib/futurehome/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\: /var/lib/futurehome/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\: /opt/thingsplex/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chown ecollector\: /opt/thingsplex/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\: /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chown kindowl\: /opt/thingsplex/kind-owl/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/chown energy-guard\: /var/lib/futurehome/energy-guard/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/chown energy-guard\: /var/lib/futurehome/energy-guard/data.db
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /opt/thingsplex/ecollector/data/config.json
%fh-backup-restore ALL=(ecollector) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /opt/thingsplex/ecollector/data/proc/influxdb.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/kind-owl/config.json
%fh-backup-restore ALL=(kindowl) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /opt/thingsplex/kind-owl/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/energy-guard/config.json
%fh-backup-restore ALL=(energy-guard) NOPASSWD: /bin/chmod 0[0-7][0-7][0-7] /var/lib/futurehome/energy-guard/data.db
