From: Paul Eggert Date: Mon, 18 Jul 2011 17:21:18 +0000 (-0700) Subject: * fileio.c (Fcopy_file): Adjust mode if fchown fails. (Bug#9002) X-Git-Tag: emacs-pretest-24.0.90~104^2~202 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=b59b67c56e338162437c045a8a0e2156bcde9a0b;p=emacs.git * fileio.c (Fcopy_file): Adjust mode if fchown fails. (Bug#9002) If fchown fails to set both uid and gid, try to set just gid, as that is sometimes allowed. Adjust the file's mode to eliminate setuid or setgid bits that are inappropriate if fchown fails. --- diff --git a/src/ChangeLog b/src/ChangeLog index a2891fa9c91..5de5fefd6aa 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2011-07-18 Paul Eggert + + * fileio.c (Fcopy_file): Adjust mode if fchown fails. (Bug#9002) + If fchown fails to set both uid and gid, try to set just gid, + as that is sometimes allowed. Adjust the file's mode to eliminate + setuid or setgid bits that are inappropriate if fchown fails. + 2011-07-18 Stefan Monnier * xdisp.c (next_element_from_string, next_element_from_buffer): Use EQ diff --git a/src/fileio.c b/src/fileio.c index a52e834c2b2..fb2c081ae5c 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -38,8 +38,6 @@ along with GNU Emacs. If not, see . */ #include #endif -#include - #include "lisp.h" #include "intervals.h" #include "buffer.h" @@ -1961,9 +1959,21 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) owner and group. */ if (input_file_statable_p) { + int mode_mask = 07777; if (!NILP (preserve_uid_gid)) - ignore_value (fchown (ofd, st.st_uid, st.st_gid)); - if (fchmod (ofd, st.st_mode & 07777) != 0) + { + /* Attempt to change owner and group. If that doesn't work + attempt to change just the group, as that is sometimes allowed. + Adjust the mode mask to eliminate setuid or setgid bits + that are inappropriate if the owner and group are wrong. */ + if (fchown (ofd, st.st_uid, st.st_gid) != 0) + { + mode_mask &= ~06000; + if (fchown (ofd, -1, st.st_gid) == 0) + mode_mask |= 02000; + } + } + if (fchmod (ofd, st.st_mode & mode_mask) != 0) report_file_error ("Doing chmod", Fcons (newname, Qnil)); } #endif /* not MSDOS */