aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2015-07-08 00:10:07 +0300
committerZyX <kp-pav@yandex.ru>2015-10-08 22:00:09 +0300
commitb905c8a942a74aa350c6c50def02d1f6e7b56091 (patch)
treeb882873345a4e09438d43ee88ba1e568e596d4b4
parent1d3823a5c9c7b7494966d4e0851e2c1decbed76c (diff)
downloadrneovim-b905c8a942a74aa350c6c50def02d1f6e7b56091.tar.gz
rneovim-b905c8a942a74aa350c6c50def02d1f6e7b56091.tar.bz2
rneovim-b905c8a942a74aa350c6c50def02d1f6e7b56091.zip
shada: Preserve existing file permissions
-rw-r--r--src/nvim/shada.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 3dbd24b7ea..743adfb20f 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -82,6 +82,8 @@ KHASH_SET_INIT_STR(strset)
(buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
#define convert_setup(vcp, from, to) \
(convert_setup(vcp, (char_u *)from, (char_u *)to))
+#define os_getperm(f) \
+ (os_getperm((char_u *) f))
// From http://www.boost.org/doc/libs/1_43_0/boost/detail/endian.hpp + some
// additional checks done after examining `{compiler} -dM -E - < /dev/null`
@@ -1810,16 +1812,41 @@ int shada_write_file(const char *const file, bool nomerge)
nomerge = true;
goto shada_write_file_nomerge;
}
+#ifdef UNIX
+ // For Unix we check the owner of the file. It's not very nice to
+ // overwrite a user’s viminfo file after a "su root", with a
+ // viminfo file that the user can't read.
+ FileInfo old_info;
+ if (os_fileinfo((char *)fname, &old_info)
+ && getuid() != ROOT_UID
+ && !(old_info.stat.st_uid == getuid()
+ ? (old_info.stat.st_mode & 0200)
+ : (old_info.stat.st_gid == getgid()
+ ? (old_info.stat.st_mode & 0020)
+ : (old_info.stat.st_mode & 0002)))) {
+ EMSG2(_("E137: ShaDa file is not writable: %s"), fname);
+ close_file((int)(intptr_t) sd_reader.cookie);
+ xfree(fname);
+ return FAIL;
+ }
+#endif
tempname = modname(fname, ".tmp.a", false);
if (tempname == NULL) {
nomerge = true;
goto shada_write_file_nomerge;
}
+ // Save permissions from the original file, with modifications:
+ int perm = (int) os_getperm(fname);
+ perm = (perm >= 0) ? ((perm & 0777) | 0600) : 0600;
+ // ^3 ^1 ^2 ^2,3
+ // 1: Strip SUID bit if any.
+ // 2: Make sure that user can always read and write the result.
+ // 3: If somebody happened to delete the file after it was opened for
+ // reading use u=rw permissions.
shada_write_file_open:
- // TODO(ZyX-I): Preserve existing permissions
fd = (intptr_t) open_file(tempname, O_CREAT|O_WRONLY|O_NOFOLLOW|O_EXCL,
- 0600);
+ perm);
if (fd < 0) {
if (-fd == EEXIST
#ifdef ELOOP