diff --git a/src/borg/helpers/fs.py b/src/borg/helpers/fs.py index a2ac49876..d1a412da0 100644 --- a/src/borg/helpers/fs.py +++ b/src/borg/helpers/fs.py @@ -21,12 +21,12 @@ logger = create_logger() py_37_plus = sys.version_info >= (3, 7) -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, diff --git a/src/borg/platform/base.py b/src/borg/platform/base.py index 1eb929ee2..2bd712cf6 100644 --- a/src/borg/platform/base.py +++ b/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 from borg.platformflags import is_win32 @@ -237,6 +238,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: