rdiff-backup and regular users
Damon Timm asks an interesting question today on rdiff-backup users list. He wants to do a backup of home folders of users within a system, leaving each users full access to its backuped data so they can restore it when they want, without making a cron entry for each user. I think its an useful feature if you have a system with many users. So, here’s my approach to a solution, a tiny bash script based on “sudo” and “stat” commands:
for DNAME in $(find /home -maxdepth 1 -mindepth 1 -type d); do USER=$(stat -c %U $DNAME); GROUP=$(stat -c %G $DNAME); sudo mkdir -p /backups/$USER; sudo chown $USER:$GROUP /backups/$USER; sudo -u $USER rdiff-backup --preserve-numerical-ids $DNAME /backups/$USER; done
Of course its not too flexible, if you want not to do backup copy of every /home subdir, also it does not control if a user has files that he dont own on his home directory, but I still think its a good approach for a more elaborated and more complex solution.


It seems to be a bug on rdiff-backup, its not preserving ownership information for files. See this, as I told in rdiff-backup user list in response to another Damon message:
fmmarzoa@durruti:~$ ls -al test
total 8
drwxr-xr-x 2 fmmarzoa devel 4096 2009-02-23 20:07 .
drwxr-xr-x 77 fmmarzoa fmmarzoa 4096 2009-02-23 20:07 ..
-rw-r–r– 1 fmmarzoa devel 0 2009-02-23 20:07 testfile
I’ve a directory called “test” with uid:gid as fmmarzoa:devel, and a testfile within the directory with same ownership. Now I backup it with:
fmmarzoa@durruti:~$ rdiff-backup –preserve-numerical-ids test test_backup
fmmarzoa@durruti:~$ ls -la test_backup
total 12
drwxr-xr-x 3 fmmarzoa fmmarzoa 4096 2009-02-23 20:07 .
drwxr-xr-x 78 fmmarzoa fmmarzoa 4096 2009-02-23 20:10 ..
drwx—— 3 fmmarzoa fmmarzoa 4096 2009-02-23 20:10 rdiff-backup-data
-rw-r–r– 1 fmmarzoa fmmarzoa 0 2009-02-23 20:07 testfile
So in fact, ownership information has been lost. Obviously restoring just doing a “cp test_backup test” will not recover the ownership data, but restore command neither!:
fmmarzoa@durruti:~$ rdiff-backup -r now test_backup test
fmmarzoa@durruti:~$ ls -la test
total 8
drwxr-xr-x 2 fmmarzoa fmmarzoa 4096 2009-02-23 20:07 .
drwxr-xr-x 78 fmmarzoa fmmarzoa 4096 2009-02-23 20:12 ..
-rw-r–r– 1 fmmarzoa fmmarzoa 0 2009-02-23 20:07 testfile
It seems to be a bug, or a missunderstanding of –perserve-numerical-ids by me.
BTW:
fmmarzoa@durruti:~$ rdiff-backup -V
rdiff-backup 1.1.15
As a workaround, on a local fs file ownership may be cloned using find+stat+chown, its a bit tricky but for remote copies it will be helpless.
I opened a bug report, and Damon commented it also:
http://savannah.nongnu.org/bugs/?25684
This is not a bug. As Chris Wilson says on the list:
“As Damon Timm pointed out, preserving any kind of ownership does not work when you run the restore as a non-root user. Unix does not allow non-root users (including rdiff-backup when run on your behalf) to change the owner of files. They will always be owned by the user that you are running as. If you run the restore as root, then ownership should be preserved either by name or by UID.”
In fact, every modern UNiX systems doesn’t let you chown as regular user, so there’s simply no way to restore file owner without being root. SUID is not a solution neither, as scripts cannot run as suid. Perhaps with a little C program with suid that calls chown but checking first that the user is changing owner to a file within a given directory or so…
One workaround could be running some script on root’s cron running every five minutes or less, in a manner that a user can make a request to recover files and then that script recover them in next cron execution. Of course the script should check than the user wants to recover something that he owns, and in a place that he owns also.
To asure that the user doesnt do bad things, one idea is that every directories specified by him will be relative to his backup and home dirs. For example, if user “pepe” says:
recover /bin /bin
We’ll try to run:
rdiff-backup /backup/pepe/bin /home/pepe/bin
and not:
rdiff-backup /backup/bin /bin
We will also need to check that there’s no dots on path in the way of:
recover ../bin
Because:
rdiff-backup /backup/pepe/../bin
is the same of
rdiff-backup /backup/bin
It may be very easy to do something like this on perl.
I’m stupid: Instead of using cron, you can run your script as a daemon, open a socket, and wait there for petitions. Then they’ll be resolved live as user does.
I’m working on a perl script for that on my “spare” time, may be it’ll be working next week or so.
BTW, I want to put here a link to Damon’s blog, as I found it very interesting: http://blog.damontimm.com/