summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-07-18 10:21:18 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2011-07-18 10:21:18 -0700
commitb59b67c56e338162437c045a8a0e2156bcde9a0b (patch)
treeca1307f544e189aa8c1125d353aaf76c2a038559 /src
parentbf2c1571f4085d3b52f37370f0bcdf7a23c53a50 (diff)
downloademacs-b59b67c56e338162437c045a8a0e2156bcde9a0b.tar.gz
* 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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog7
-rw-r--r--src/fileio.c18
2 files changed, 21 insertions, 4 deletions
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 <eggert@cs.ucla.edu>
+
+ * 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 <monnier@iro.umontreal.ca>
* 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 <http://www.gnu.org/licenses/>. */
#include <selinux/context.h>
#endif
-#include <ignore-value.h>
-
#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 */