From 3ddac7b88ec498ed70ed177a830e943ae1c3a627 Mon Sep 17 00:00:00 2001 From: bescoto Date: Thu, 20 Oct 2005 20:20:29 +0000 Subject: Fix for bug #14799 -- now autodetect whether destination supports high permissions git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@639 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109 --- rdiff-backup/CHANGELOG | 3 +++ rdiff-backup/rdiff_backup/Globals.py | 4 ++++ rdiff-backup/rdiff_backup/Main.py | 5 +++++ rdiff-backup/rdiff_backup/fs_abilities.py | 15 ++++++++++++++- rdiff-backup/rdiff_backup/rpath.py | 2 +- rdiff-backup/testing/fs_abilitiestest.py | 2 ++ 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG index bde1767..9d387a2 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -8,6 +8,9 @@ Support req 104755: Added --preserve-numerical-ids option, which makes rdiff-backup preserve uids/gids instead of unames/gnames. (Suggested by Wiebe Cazemier) +Fix for bug #14799 reported by Bob McKay: Crash when backing up files +with high permissions (like suid) to some FAT systems. + New in v1.0.2 (????/??/??) -------------------------- diff --git a/rdiff-backup/rdiff_backup/Globals.py b/rdiff-backup/rdiff_backup/Globals.py index 710d79d..9a34238 100644 --- a/rdiff-backup/rdiff_backup/Globals.py +++ b/rdiff-backup/rdiff_backup/Globals.py @@ -216,6 +216,10 @@ fsync_directories = None # If set, exit with error instead of dropping ACLs or ACL entries. never_drop_acls = None +# Apply this mask to permissions before chmoding. (Set to 0777 to +# prevent highbit permissions on systems which don't support them.) +permission_mask = 07777 + def get(name): """Return the value of something in this module""" diff --git a/rdiff-backup/rdiff_backup/Main.py b/rdiff-backup/rdiff_backup/Main.py index 4a6450d..8946572 100644 --- a/rdiff-backup/rdiff_backup/Main.py +++ b/rdiff-backup/rdiff_backup/Main.py @@ -450,6 +450,8 @@ def backup_set_fs_globals(rpin, rpout): SetConnections.UpdateGlobal('fsync_directories', dest_fsa.fsync_dirs) SetConnections.UpdateGlobal('change_ownership', dest_fsa.ownership) SetConnections.UpdateGlobal('chars_to_quote', dest_fsa.chars_to_quote) + if not dest_fsa.high_perms: + SetConnections.UpdateGlobal('permission_mask', 0777) if Globals.chars_to_quote: FilenameMapping.set_init_quote_vals() def backup_touch_curmirror_local(rpin, rpout): @@ -555,6 +557,8 @@ def restore_set_fs_globals(target): if Globals.preserve_hardlinks != 0: SetConnections.UpdateGlobal('preserve_hardlinks', target_fsa.hardlinks) SetConnections.UpdateGlobal('change_ownership', target_fsa.ownership) + if not target_fsa.high_perms: + SetConnections.UpdateGlobal('permission_mask', 0777) if Globals.chars_to_quote is None: # otherwise already overridden if mirror_fsa.chars_to_quote: @@ -735,6 +739,7 @@ def single_set_fs_globals(rbdir): SetConnections.UpdateGlobal('preserve_hardlinks', fsa.hardlinks) SetConnections.UpdateGlobal('fsync_directories', fsa.fsync_dirs) SetConnections.UpdateGlobal('change_ownership', fsa.ownership) + if not fsa.high_perms: SetConnections.UpdateGlobal('permission_mask', 0777) SetConnections.UpdateGlobal('chars_to_quote', fsa.chars_to_quote) if Globals.chars_to_quote: for conn in Globals.connections: diff --git a/rdiff-backup/rdiff_backup/fs_abilities.py b/rdiff-backup/rdiff_backup/fs_abilities.py index b3d69a0..e2285e7 100644 --- a/rdiff-backup/rdiff_backup/fs_abilities.py +++ b/rdiff-backup/rdiff_backup/fs_abilities.py @@ -43,6 +43,7 @@ class FSAbilities: carbonfile = None # True if Mac Carbon file data is supported. name = None # Short string, not used for any technical purpose read_only = None # True if capabilities were determined non-destructively + high_perms = None # True if suid etc perms are (read/write) supported def __init__(self, name = None): """FSAbilities initializer. name is only used in logging""" @@ -89,7 +90,8 @@ class FSAbilities: ('Hard linking', self.hardlinks), ('fsync() directories', self.fsync_dirs), ('Directory inc permissions', - self.dir_inc_perms)]) + self.dir_inc_perms), + ('High-bit permissions', self.high_perms)]) add_boolean_list([('Access control lists', self.acls), ('Extended attributes', self.eas), ('Mac OS X style resource forks', @@ -149,6 +151,7 @@ class FSAbilities: self.set_dir_inc_perms(subdir) self.set_resource_fork_readwrite(subdir) self.set_carbonfile() + self.set_high_perms_readwrite(subdir) if override_chars_to_quote is None: self.set_chars_to_quote(subdir) else: self.chars_to_quote = override_chars_to_quote if use_ctq_file: self.compare_chars_to_quote(rbdir) @@ -378,6 +381,16 @@ rdiff-backup-data/chars_to_quote. return self.resource_forks = 0 + def set_high_perms_readwrite(self, dir_rp): + """Test for writing high-bit permissions like suid""" + tmp_rp = dir_rp.append("high_perms") + tmp_rp.touch() + try: + tmp_rp.chmod(07000) + tmp_rp.chmod(07777) + except (OSError, IOError), e: self.high_perms = 0 + else: self.high_perms = 1 + tmp_rp.delete() def get_fsabilities_readonly(desc_string, rp): """Return an FSAbilities object with given description_string diff --git a/rdiff-backup/rdiff_backup/rpath.py b/rdiff-backup/rdiff_backup/rpath.py index 8213a23..33d1224 100644 --- a/rdiff-backup/rdiff_backup/rpath.py +++ b/rdiff-backup/rdiff_backup/rpath.py @@ -757,7 +757,7 @@ class RPath(RORPath): def chmod(self, permissions): """Wrapper around os.chmod""" - self.conn.os.chmod(self.path, permissions) + self.conn.os.chmod(self.path, permissions & Globals.permission_mask) self.data['perms'] = permissions def settime(self, accesstime, modtime): diff --git a/rdiff-backup/testing/fs_abilitiestest.py b/rdiff-backup/testing/fs_abilitiestest.py index da7198a..1aa3f68 100644 --- a/rdiff-backup/testing/fs_abilitiestest.py +++ b/rdiff-backup/testing/fs_abilitiestest.py @@ -20,6 +20,7 @@ class FSAbilitiesTest(unittest.TestCase): dir_inc_perms = 1 resource_forks = 0 carbonfile = 0 + high_perms = 1 # Describes MS-Windows style file system #dir_to_test = "/mnt/fat" @@ -63,6 +64,7 @@ class FSAbilitiesTest(unittest.TestCase): assert fsa.dir_inc_perms == self.dir_inc_perms, fsa.dir_inc_perms assert fsa.resource_forks == self.resource_forks, fsa.resource_forks assert fsa.carbonfile == self.carbonfile, fsa.carbonfile + assert fsa.high_perms == self.high_perms, fsa.high_perms ctq_rp = new_dir.append("chars_to_quote") assert ctq_rp.lstat() -- cgit v1.2.1