Browse Source

Merge pull request #6430 from ThomasWaldmann/fix-savefile-mode-1.1

respect umask for files / dirs (1.1)
TW 3 years ago
parent
commit
111a420420
2 changed files with 12 additions and 2 deletions
  1. 2 2
      src/borg/helpers.py
  2. 10 0
      src/borg/platform/base.py

+ 2 - 2
src/borg/helpers.py

@@ -513,12 +513,12 @@ def prune_split(archives, pattern, n, skip=[]):
     return keep
 
 
-def ensure_dir(path, mode=stat.S_IRWXU, pretty_deadly=True):
+def ensure_dir(path, mode=stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO, pretty_deadly=True):
     """
     Ensures that the dir exists with the right permissions.
     1) Make sure the directory exists in a race-free operation
     2) If mode is not None and the directory has been created, give the right
-    permissions to the leaf directory
+    permissions to the leaf directory. The current umask value is masked out first.
     3) If pretty_deadly is True, catch exceptions, reraise them with a pretty
     message.
     Returns if the directory has been created and has the right permissions,

+ 10 - 0
src/borg/platform/base.py

@@ -4,6 +4,7 @@ import socket
 import tempfile
 import uuid
 
+from borg.constants import UMASK_DEFAULT
 from borg.helpers import safe_unlink
 
 """
@@ -193,6 +194,15 @@ class SaveFile:
         if exc_type is not None:
             safe_unlink(self.tmp_fname)  # with-body has failed, clean up tmp file
             return  # continue processing the exception normally
+
+        # tempfile.mkstemp always uses owner-only file permissions for the temp file,
+        # but as we'll rename it to the non-temp permanent file now, we need to respect
+        # the umask and change the file mode to what a normally created file would have.
+        # thanks to the crappy os.umask api, we can't query the umask without setting it. :-(
+        umask = os.umask(UMASK_DEFAULT)
+        os.umask(umask)
+        os.chmod(self.tmp_fname, mode=0o666 & ~ umask)
+
         try:
             os.replace(self.tmp_fname, self.path)  # POSIX: atomic rename
         except OSError: