From 799dad58cef1646126a65e5df343a3d15f412539 Mon Sep 17 00:00:00 2001 From: bescoto Date: Thu, 20 Oct 2005 20:43:50 +0000 Subject: Fix for bug #14799 - autodetect whether destination handles highbit perms git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/branches/r1-0@640 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 5233609..f38efbb 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -13,6 +13,9 @@ If you know something about Mac OS X and want to look at the carbonfile code so it can be re-enabled by default, please do so :) (help available from list) +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.1 (2005/09/10) -------------------------- 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 62ce7fc..2bed0c2 100644 --- a/rdiff-backup/rdiff_backup/Main.py +++ b/rdiff-backup/rdiff_backup/Main.py @@ -441,6 +441,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): @@ -546,6 +548,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: @@ -726,6 +730,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 95dd54f..15f4a59 100644 --- a/rdiff-backup/rdiff_backup/rpath.py +++ b/rdiff-backup/rdiff_backup/rpath.py @@ -756,7 +756,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