--change-source-perms

dean gaudet dean-list-rdiff-backup@arctic.org
Fri, 17 May 2002 17:47:46 -0700 (PDT)


before using rdiff-backup, i used tar ... and tar never complained about
several dozen files on my system which have no read permission.  but
rdiff-backup started complaining, until i put in the --change-source-perms
option.  unfortunately i can't use this option when i'm doing the backup
from a read-only snapshot.

i looked at an strace of tar -- and when running as root, it has no
problems opening a file for reading, even when the file has no read
permissions for any user:

lstat64("a1/unread", {st_mode=S_IFREG, st_size=0, ...}) = 0
open("a1/unread", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG, st_size=0, ...}) = 0
close(4)                                = 0

studying an strace of rdiff-backup (without --change-source-perms) i
notice that it doesn't even attempt to open the file:

lstat64("a1/unread", {st_mode=S_IFREG, st_size=0, ...}) = 0
write(2, "Received error \'No read permissi"..., 83) = 83

it'd be preferable to behave more like tar -- attempt the open()
regardless of what the permissions are.  similarly, root is able to
opendir() regardless of permissions.

the patch below is a hack ... i think it's preferable to try the
open()/opendir() and use the results of that to decide whether to try
--change-source-perms.  the hack in the patch just assumes root can
open()/opendir().  in my quest for better security for the backup i'm
going to be investigating non-root users which can do read-only opens of
everything... which is why i think hard-coding root is a hack.

but anyhow, here's the patch against 0.7.4 :)  it's my first python, hee.

-dean

--- rdiff-backup.orig	Tue May 14 21:39:56 2002
+++ rdiff-backup	Fri May 17 17:43:31 2002
@@ -3706,7 +3706,8 @@

 	def set_init_perms(self, source):
 		"""If necessary, change permissions to ensure access"""
-		if self.isreg() and not self.readable():
+		if self.conn.Globals.get('process_uid') == 0: return
+		elif self.isreg() and not self.readable():
 			if not source or Globals.change_source_perms and self.isowner():
 				self.chmod_bypass(0400)
 			else: self.warn("No read permissions")