summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-10-20 20:20:29 +0000
committerbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-10-20 20:20:29 +0000
commit3ddac7b88ec498ed70ed177a830e943ae1c3a627 (patch)
treec860e93373fb44c3fd8b532677f267ca27265f30
parent11ec1472b7b88996c8da45a1d737e2e59e554de0 (diff)
downloadrdiff-backup-3ddac7b88ec498ed70ed177a830e943ae1c3a627.tar.gz
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
-rw-r--r--rdiff-backup/CHANGELOG3
-rw-r--r--rdiff-backup/rdiff_backup/Globals.py4
-rw-r--r--rdiff-backup/rdiff_backup/Main.py5
-rw-r--r--rdiff-backup/rdiff_backup/fs_abilities.py15
-rw-r--r--rdiff-backup/rdiff_backup/rpath.py2
-rw-r--r--rdiff-backup/testing/fs_abilitiestest.py2
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()