From 78168105def44c786da0291aff0706fbd339fa40 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 17 Dec 2005 07:58:12 +0000 Subject: Two changes in the HIST_SAVE_BY_COPY code: (1) preserve the group and permissions on the history file, and (2) fail if zsh's euid differs from the file's uid (since that would change the history file's owner). --- Src/hist.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Src/hist.c b/Src/hist.c index 90e97313e..1a9140801 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2080,8 +2080,26 @@ savehistfile(char *fn, int err, int writeflags) tmpfile = bicat(unmeta(fn), ".new"); if (unlink(tmpfile) < 0 && errno != ENOENT) out = NULL; - else - out = fdopen(open(tmpfile, O_CREAT | O_WRONLY | O_EXCL, 0600), "w"); + else { + struct stat sb; + int old_exists = stat(unmeta(fn), &sb) == 0; + + if (old_exists && sb.st_uid != geteuid()) { + free(tmpfile); + tmpfile = NULL; /* Avoid an error about HISTFILE.new */ + out = NULL; + } else + out = fdopen(open(tmpfile, O_CREAT | O_WRONLY | O_EXCL, 0600), "w"); + +#ifdef HAVE_FCHMOD + if (old_exists && out) { +#ifdef HAVE_FCHOWN + fchown(fileno(out), sb.st_uid, sb.st_gid); +#endif + fchmod(fileno(out), sb.st_mode); + } +#endif + } } if (out) { for (; he && he->histnum <= xcurhist; he = down_histent(he)) { -- cgit 1.4.1