diff options
Diffstat (limited to 'gnu/packages/patches/python-execnet-read-only-fix.patch')
| -rw-r--r-- | gnu/packages/patches/python-execnet-read-only-fix.patch | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/gnu/packages/patches/python-execnet-read-only-fix.patch b/gnu/packages/patches/python-execnet-read-only-fix.patch new file mode 100644 index 00000000000..58a4b129a7c --- /dev/null +++ b/gnu/packages/patches/python-execnet-read-only-fix.patch | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | From 0d6562a20b0610c5a83d1c66ac879223b84a2746 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Maxim Cournoyer <maxim.cournoyer@gmail.com> | ||
| 3 | Date: Thu, 26 Aug 2021 00:43:26 -0400 | ||
| 4 | Subject: [PATCH] rsync_remote: Fix a problem when receiving read-only | ||
| 5 | directories. | ||
| 6 | |||
| 7 | Before this change, when the source directories hierarchy was | ||
| 8 | read-only, the read-only mode would be preserved at the destination, | ||
| 9 | preventing child directories to be recreated by a normal user (a | ||
| 10 | permission denied error, EACCES would be raised). | ||
| 11 | |||
| 12 | * execnet/rsync_remote.py (serve_rsync.receive_directory_structure): | ||
| 13 | Bitwise OR to ensure the write bit is set on received directories. | ||
| 14 | * testing/test_rsync.py (TestRSync) | ||
| 15 | <test_read_only_directories>: New test. | ||
| 16 | --- | ||
| 17 | execnet/rsync_remote.py | 8 ++++++-- | ||
| 18 | testing/test_rsync.py | 17 +++++++++++++++++ | ||
| 19 | 2 files changed, 23 insertions(+), 2 deletions(-) | ||
| 20 | |||
| 21 | diff --git a/execnet/rsync_remote.py b/execnet/rsync_remote.py | ||
| 22 | index cd5e765..55d154c 100644 | ||
| 23 | --- a/execnet/rsync_remote.py | ||
| 24 | +++ b/execnet/rsync_remote.py | ||
| 25 | @@ -35,7 +35,11 @@ def serve_rsync(channel): | ||
| 26 | os.makedirs(path) | ||
| 27 | mode = msg.pop(0) | ||
| 28 | if mode: | ||
| 29 | - os.chmod(path, mode) | ||
| 30 | + # Ensure directories are writable, otherwise a | ||
| 31 | + # permission denied error (EACCES) would be raised | ||
| 32 | + # when attempting to receive read-only directory | ||
| 33 | + # structures. | ||
| 34 | + os.chmod(path, mode | 0o700) | ||
| 35 | entrynames = {} | ||
| 36 | for entryname in msg: | ||
| 37 | destpath = os.path.join(path, entryname) | ||
| 38 | @@ -59,7 +63,7 @@ def serve_rsync(channel): | ||
| 39 | checksum = md5(f.read()).digest() | ||
| 40 | f.close() | ||
| 41 | elif msg_mode and msg_mode != st.st_mode: | ||
| 42 | - os.chmod(path, msg_mode) | ||
| 43 | + os.chmod(path, msg_mode | 0o700) | ||
| 44 | return | ||
| 45 | else: | ||
| 46 | return # already fine | ||
| 47 | diff --git a/testing/test_rsync.py b/testing/test_rsync.py | ||
| 48 | index 995f229..1d6c30c 100644 | ||
| 49 | --- a/testing/test_rsync.py | ||
| 50 | +++ b/testing/test_rsync.py | ||
| 51 | @@ -157,6 +157,23 @@ class TestRSync: | ||
| 52 | mode = destdir.stat().mode | ||
| 53 | assert mode & 511 == 504 | ||
| 54 | |||
| 55 | + @py.test.mark.skipif("sys.platform == 'win32' or getattr(os, '_name', '') == 'nt'") | ||
| 56 | + def test_read_only_directories(self, dirs, gw1): | ||
| 57 | + source = dirs.source | ||
| 58 | + dest = dirs.dest1 | ||
| 59 | + source.ensure("sub", "subsub", dir=True) | ||
| 60 | + source.join("sub").chmod(0o500) | ||
| 61 | + source.join("sub", "subsub").chmod(0o500) | ||
| 62 | + | ||
| 63 | + # The destination directories should be created with the write | ||
| 64 | + # permission forced, to avoid raising an EACCES error. | ||
| 65 | + rsync = RSync(source) | ||
| 66 | + rsync.add_target(gw1, dest) | ||
| 67 | + rsync.send() | ||
| 68 | + | ||
| 69 | + assert dest.join("sub").stat().mode & 0o700 | ||
| 70 | + assert dest.join("sub").join("subsub").stat().mode & 0o700 | ||
| 71 | + | ||
| 72 | @needssymlink | ||
| 73 | def test_symlink_rsync(self, dirs, gw1): | ||
| 74 | source = dirs.source | ||
| 75 | -- | ||
| 76 | 2.32.0 | ||
| 77 | |||
