Using ZFS snapshots on FreeBSD *without* running as root

I’m setting up a new urbackup server on FreeBSD 12.2 with ZFS. I’ve configured the correct paths in /usr/local/urbackup/dataset, dataset_file and backupfolder.

$ urbackup_snapshot_helper test
Testing for btrfs...
TEST FAILED: Creating test btrfs subvolume failed
Testing for zfs...
ZFS TEST OK

I’ve set delegated permissions on the parent zfs dataset
$ zfs allow data/urbackup
---- Permissions on data/urbackup ------------------------------------
Local+Descendent permissions:
user urbackup clone,create,destroy,diff,hold,mount,promote,release,rename,rollback,snapshot

But urbackup_snapshot_helper is setuid so snapshots are created with owner root and backups fail

2021-06-14 14:08:43: ERROR: Error opening /var/backups/backup.example.com/210614-1408/.hashes/.urbackup_tokens.properties
2021-06-14 14:08:43: backup.example.com: Deleting files in snapshot... (0)
2021-06-14 14:08:43: backup.example.com: Deleting files in hash snapshot...(0)
2021-06-14 14:08:43: backup.example.com: Calculating tree difference size...
2021-06-14 14:08:43: backup.example.com: Linking unchanged and loading new files...
2021-06-14 14:08:43: Waiting for file transfers...
2021-06-14 14:08:44: Referencing snapshot on "backup.example.com" for path "/" failed: FAILED
2021-06-14 14:08:44: Waiting for file hashing and copying threads...
2021-06-14 14:08:45: ERROR: Error opening /var/backups/backup.example.com/210614-1408/.hashes/.urbackup_tokens.properties
2021-06-14 14:08:45: Writing new file list...
2021-06-14 14:08:45: All metadata was present
2021-06-14 14:08:45: ERROR: Error creating sync file at /var/backups/backup.example.com/210614-1408/.hashes/.sync_f3a50226-f49a-4195-afef-c75b21781ae1. Not setting backup to done.
2021-06-14 14:08:45: Transferred 1.16895 KB - Average speed: 17.096 KBit/s
2021-06-14 14:08:52: ERROR: Sending broadcast failed! (ipv6)
2021-06-14 14:08:52: ERROR: Sending broadcast failed! (ipv6)
2021-06-14 14:08:53: Time taken for backing up client backup.example.com: 10s
2021-06-14 14:08:53: ERROR: Backup failed
2021-06-14 14:08:53: Updating statistics...
2021-06-14 14:08:53: Updating image stats...
2021-06-14 14:08:53: Updating file statistics...
2021-06-14 14:08:53: Done updating statistics.
2021-06-14 14:08:54: WARNING: Exponential backoff: Waiting at least 1h 20m before next file backup
2021-06-14 14:08:54: server_prepare_hash Thread finished (exit)
2021-06-14 14:08:54: server_hash Thread finished - normal

We can’t remove setuid from urbackup_snapshot_helper since the code excplicitely checks if it’s running with uid 0. Any trick to configure the dataset to create all files and child datasets with uid of the urbackup user or to chown the files after snapshot and mount, but before the backup runs?

I dug a little deeper and found a bug in urbackup_snapshot_helper. It calls chown after creating the dataset/snapshot, but passes the dataset path instead of the mounted file system path.

I’ve made a PR with a fix at chown() needs the fs path, so call zfs get -o mountpoint to get from … by einsibjarni · Pull Request #52 · uroni/urbackup_backend · GitHub

My patch had serious errors (wrong parameters to zfs get and didn’t call trim on the results).

I fixed it up and created a new PR