diff options
author | Wayne Davison <wayned@users.sourceforge.net> | 2005-12-17 07:58:12 +0000 |
---|---|---|
committer | Wayne Davison <wayned@users.sourceforge.net> | 2005-12-17 07:58:12 +0000 |
commit | 78168105def44c786da0291aff0706fbd339fa40 (patch) | |
tree | 632741cbd4f74f0d291aa2025c1c28e5f3d9e54d /Src | |
parent | f7037211ad3a9e4f61a5d1aad8eceab5e01b4663 (diff) | |
download | zsh-78168105def44c786da0291aff0706fbd339fa40.tar.gz zsh-78168105def44c786da0291aff0706fbd339fa40.tar.xz zsh-78168105def44c786da0291aff0706fbd339fa40.zip |
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).
Diffstat (limited to 'Src')
-rw-r--r-- | Src/hist.c | 22 |
1 files 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)) { |