Set replacement file permissions before moving into place
When doing :write -method replace, make sure we've set the correct mode, uid and gid on the replacement file before attempting to rename it on top of the original. This means that the original file is left in place with correct permissions if anything fails, rather than ending up with 0700 permissions from mkstemp().
This commit is contained in:
parent
d3af9b57d4
commit
3ba3399f94
12
src/file.cc
12
src/file.cc
|
@ -369,6 +369,13 @@ void write_buffer_to_file(Buffer& buffer, StringView filename,
|
||||||
::fsync(fd);
|
::fsync(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (replace and geteuid() == 0 and ::chown(temp_filename, st.st_uid, st.st_gid) < 0)
|
||||||
|
throw runtime_error(format("unable to set replacement file ownership: {}", strerror(errno)));
|
||||||
|
if (replace and ::chmod(temp_filename, st.st_mode) < 0)
|
||||||
|
throw runtime_error(format("unable to set replacement file permissions: {}", strerror(errno)));
|
||||||
|
if (force and not replace and ::chmod(zfilename, st.st_mode) < 0)
|
||||||
|
throw runtime_error(format("unable to restore file permissions: {}", strerror(errno)));
|
||||||
|
|
||||||
if (replace and rename(temp_filename, zfilename) != 0)
|
if (replace and rename(temp_filename, zfilename) != 0)
|
||||||
{
|
{
|
||||||
if (force)
|
if (force)
|
||||||
|
@ -376,11 +383,6 @@ void write_buffer_to_file(Buffer& buffer, StringView filename,
|
||||||
throw runtime_error("replacing file failed");
|
throw runtime_error("replacing file failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replace and geteuid() == 0 and ::chown(zfilename, st.st_uid, st.st_gid) < 0)
|
|
||||||
throw runtime_error(format("unable to restore file ownership: {}", strerror(errno)));
|
|
||||||
if ((force or replace) and ::chmod(zfilename, st.st_mode) < 0)
|
|
||||||
throw runtime_error(format("unable to restore file permissions: {}", strerror(errno)));
|
|
||||||
|
|
||||||
if ((buffer.flags() & Buffer::Flags::File) and
|
if ((buffer.flags() & Buffer::Flags::File) and
|
||||||
real_path(filename) == real_path(buffer.name()))
|
real_path(filename) == real_path(buffer.name()))
|
||||||
buffer.notify_saved(get_fs_status(real_path(filename)));
|
buffer.notify_saved(get_fs_status(real_path(filename)));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user