diff options
| author | Paul Eggert | 2012-12-14 10:59:00 -0800 |
|---|---|---|
| committer | Paul Eggert | 2012-12-14 10:59:00 -0800 |
| commit | 97976f9f3fcf588535bf4afad71de92860bb2f8e (patch) | |
| tree | 48af44cc93624fd119f59ceb94fbb5c5f3eaaf7c /lisp | |
| parent | ad966fe7542070b5c9aa34ed019d586e7c3adae6 (diff) | |
| download | emacs-97976f9f3fcf588535bf4afad71de92860bb2f8e.tar.gz emacs-97976f9f3fcf588535bf4afad71de92860bb2f8e.zip | |
Fix permissions bugs with setgid directories etc.
* configure.ac (BSD4_2): Remove; no longer needed.
* admin/CPP-DEFINES (BSD4_2): Remove.
* doc/lispintro/emacs-lisp-intro.texi (Files List):
directory-files-and-attributes now outputs t for attribute that's
now a placeholder.
* doc/lispref/files.texi (Testing Accessibility): Document GROUP arg
of file-ownership-preserved-p.
(File Attributes): Document that 9th element is now
just a placeholder.
* doc/lispref/os.texi (User Identification): Document new functions group-gid,
group-real-gid.
* etc/NEWS: Document changes to file-attributes,
file-ownership-preserved-p.
Mention new functions group-gid, group-real-gid.
* lisp/files.el (backup-buffer): Don't rely on 9th output of
file-attributes, as it's now a placeholder. Instead, use the new
optional arg of file-ownership-preserved-p.
(file-ownership-preserved-p): New optional arg GROUP.
Fix mishandling of setuid directories that would cause this
function to return t when it should have returned nil.
Document what happens if the file does not exist, and when
it's not known whether the ownership will be preserved.
* lisp/net/tramp-sh.el (tramp-sh-handle-file-ownership-preserved-p):
Likewise.
(tramp-get-local-gid): Use group-gid for integer, as that's
faster and more reliable.
* src/dired.c (Ffile_attributes): Return t as the 9th attribute,
to mark it as a placeholder. The old value was often wrong.
The only user of this attribute has been changed to use
file-ownership-preserved-p instead, with its new group arg.
* src/editfns.c (Fgroup_gid, Fgroup_real_gid): New functions.
Fixes: debbugs:13125
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 16 | ||||
| -rw-r--r-- | lisp/files.el | 46 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 11 |
3 files changed, 58 insertions, 15 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 75387673f76..15cdb5cb879 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,19 @@ | |||
| 1 | 2012-12-14 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix permissions bugs with setgid directories etc. (Bug#13125) | ||
| 4 | * files.el (backup-buffer): Don't rely on 9th output of | ||
| 5 | file-attributes, as it's now a placeholder. Instead, use the new | ||
| 6 | optional arg of file-ownership-preserved-p. | ||
| 7 | (file-ownership-preserved-p): New optional arg GROUP. | ||
| 8 | Fix mishandling of setuid directories that would cause this | ||
| 9 | function to return t when it should have returned nil. | ||
| 10 | Document what happens if the file does not exist, and when | ||
| 11 | it's not known whether the ownership will be preserved. | ||
| 12 | * net/tramp-sh.el (tramp-sh-handle-file-ownership-preserved-p): | ||
| 13 | Likewise. | ||
| 14 | (tramp-get-local-gid): Use group-gid for integer, as that's | ||
| 15 | faster and more reliable. | ||
| 16 | |||
| 1 | 2012-12-14 Julien Danjou <julien@danjou.info> | 17 | 2012-12-14 Julien Danjou <julien@danjou.info> |
| 2 | 18 | ||
| 3 | * progmodes/sql.el (sql-mode-postgres-font-lock-keywords): Update | 19 | * progmodes/sql.el (sql-mode-postgres-font-lock-keywords): Update |
diff --git a/lisp/files.el b/lisp/files.el index c8a75f67820..7974f73a248 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -3941,8 +3941,8 @@ BACKUPNAME is the backup file name, which is the old file renamed." | |||
| 3941 | (and (integerp (nth 2 attr)) | 3941 | (and (integerp (nth 2 attr)) |
| 3942 | (integerp backup-by-copying-when-privileged-mismatch) | 3942 | (integerp backup-by-copying-when-privileged-mismatch) |
| 3943 | (<= (nth 2 attr) backup-by-copying-when-privileged-mismatch))) | 3943 | (<= (nth 2 attr) backup-by-copying-when-privileged-mismatch))) |
| 3944 | (or (nth 9 attr) | 3944 | (not (file-ownership-preserved-p |
| 3945 | (not (file-ownership-preserved-p real-file-name))))))) | 3945 | real-file-name t)))))) |
| 3946 | (backup-buffer-copy real-file-name backupname modes context) | 3946 | (backup-buffer-copy real-file-name backupname modes context) |
| 3947 | ;; rename-file should delete old backup. | 3947 | ;; rename-file should delete old backup. |
| 3948 | (rename-file real-file-name backupname t) | 3948 | (rename-file real-file-name backupname t) |
| @@ -4019,22 +4019,44 @@ See also `file-name-version-regexp'." | |||
| 4019 | (string-match (concat file-name-version-regexp "\\'") | 4019 | (string-match (concat file-name-version-regexp "\\'") |
| 4020 | name)))))) | 4020 | name)))))) |
| 4021 | 4021 | ||
| 4022 | (defun file-ownership-preserved-p (file) | 4022 | (defun file-ownership-preserved-p (file &optional group) |
| 4023 | "Return t if deleting FILE and rewriting it would preserve the owner." | 4023 | "Return t if deleting FILE and rewriting it would preserve the owner. |
| 4024 | Return nil if FILE does not exist, or if deleting and recreating it | ||
| 4025 | might not preserve the owner. If GROUP is non-nil, check whether | ||
| 4026 | the group would be preserved too." | ||
| 4024 | (let ((handler (find-file-name-handler file 'file-ownership-preserved-p))) | 4027 | (let ((handler (find-file-name-handler file 'file-ownership-preserved-p))) |
| 4025 | (if handler | 4028 | (if handler |
| 4026 | (funcall handler 'file-ownership-preserved-p file) | 4029 | (funcall handler 'file-ownership-preserved-p file group) |
| 4027 | (let ((attributes (file-attributes file 'integer))) | 4030 | (let ((attributes (file-attributes file 'integer))) |
| 4028 | ;; Return t if the file doesn't exist, since it's true that no | 4031 | ;; Return t if the file doesn't exist, since it's true that no |
| 4029 | ;; information would be lost by an (attempted) delete and create. | 4032 | ;; information would be lost by an (attempted) delete and create. |
| 4030 | (or (null attributes) | 4033 | (or (null attributes) |
| 4031 | (= (nth 2 attributes) (user-uid)) | 4034 | (and (or (= (nth 2 attributes) (user-uid)) |
| 4032 | ;; Files created on Windows by Administrator (RID=500) | 4035 | ;; Files created on Windows by Administrator (RID=500) |
| 4033 | ;; have the Administrators group (RID=544) recorded as | 4036 | ;; have the Administrators group (RID=544) recorded as |
| 4034 | ;; their owner. Rewriting them will still preserve the | 4037 | ;; their owner. Rewriting them will still preserve the |
| 4035 | ;; owner. | 4038 | ;; owner. |
| 4036 | (and (eq system-type 'windows-nt) | 4039 | (and (eq system-type 'windows-nt) |
| 4037 | (= (user-uid) 500) (= (nth 2 attributes) 544))))))) | 4040 | (= (user-uid) 500) (= (nth 2 attributes) 544))) |
| 4041 | (or (not group) | ||
| 4042 | ;; On BSD-derived systems files always inherit the parent | ||
| 4043 | ;; directory's group, so skip the group-gid test. | ||
| 4044 | (memq system-type '(berkeley-unix darwin gnu/kfreebsd)) | ||
| 4045 | (= (nth 3 attributes) (group-gid))) | ||
| 4046 | (let* ((parent (or (file-name-directory file) ".")) | ||
| 4047 | (parent-attributes (file-attributes parent 'integer))) | ||
| 4048 | (and parent-attributes | ||
| 4049 | ;; On some systems, a file created in a setuid directory | ||
| 4050 | ;; inherits that directory's owner. | ||
| 4051 | (or | ||
| 4052 | (= (nth 2 parent-attributes) (user-uid)) | ||
| 4053 | (string-match "^...[^sS]" (nth 8 parent-attributes))) | ||
| 4054 | ;; On many systems, a file created in a setgid directory | ||
| 4055 | ;; inherits that directory's group. On some systems | ||
| 4056 | ;; this happens even if the setgid bit is not set. | ||
| 4057 | (or (not group) | ||
| 4058 | (= (nth 3 parent-attributes) | ||
| 4059 | (nth 3 attributes))))))))))) | ||
| 4038 | 4060 | ||
| 4039 | (defun file-name-sans-extension (filename) | 4061 | (defun file-name-sans-extension (filename) |
| 4040 | "Return FILENAME sans final \"extension\". | 4062 | "Return FILENAME sans final \"extension\". |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 55af0f0d96b..3008601d9ca 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -1616,7 +1616,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." | |||
| 1616 | (and (tramp-run-test "-d" (file-name-directory filename)) | 1616 | (and (tramp-run-test "-d" (file-name-directory filename)) |
| 1617 | (tramp-run-test "-w" (file-name-directory filename))))))) | 1617 | (tramp-run-test "-w" (file-name-directory filename))))))) |
| 1618 | 1618 | ||
| 1619 | (defun tramp-sh-handle-file-ownership-preserved-p (filename) | 1619 | (defun tramp-sh-handle-file-ownership-preserved-p (filename &optional group) |
| 1620 | "Like `file-ownership-preserved-p' for Tramp files." | 1620 | "Like `file-ownership-preserved-p' for Tramp files." |
| 1621 | (with-parsed-tramp-file-name filename nil | 1621 | (with-parsed-tramp-file-name filename nil |
| 1622 | (with-tramp-file-property v localname "file-ownership-preserved-p" | 1622 | (with-tramp-file-property v localname "file-ownership-preserved-p" |
| @@ -1624,7 +1624,10 @@ and gid of the corresponding user is taken. Both parameters must be integers." | |||
| 1624 | ;; Return t if the file doesn't exist, since it's true that no | 1624 | ;; Return t if the file doesn't exist, since it's true that no |
| 1625 | ;; information would be lost by an (attempted) delete and create. | 1625 | ;; information would be lost by an (attempted) delete and create. |
| 1626 | (or (null attributes) | 1626 | (or (null attributes) |
| 1627 | (= (nth 2 attributes) (tramp-get-remote-uid v 'integer))))))) | 1627 | (and |
| 1628 | (= (nth 2 attributes) (tramp-get-remote-uid v 'integer)) | ||
| 1629 | (or (not group) | ||
| 1630 | (= (nth 3 attributes) (tramp-get-remote-gid v 'integer))))))))) | ||
| 1628 | 1631 | ||
| 1629 | ;; Directory listings. | 1632 | ;; Directory listings. |
| 1630 | 1633 | ||
| @@ -5021,7 +5024,9 @@ This is used internally by `tramp-file-mode-from-int'." | |||
| 5021 | (if (equal id-format 'integer) (user-uid) (user-login-name))) | 5024 | (if (equal id-format 'integer) (user-uid) (user-login-name))) |
| 5022 | 5025 | ||
| 5023 | (defun tramp-get-local-gid (id-format) | 5026 | (defun tramp-get-local-gid (id-format) |
| 5024 | (nth 3 (tramp-compat-file-attributes "~/" id-format))) | 5027 | (if (and (fboundp 'group-gid) (equal id-format 'integer)) |
| 5028 | (tramp-compat-funcall 'group-gid) | ||
| 5029 | (nth 3 (tramp-compat-file-attributes "~/" id-format)))) | ||
| 5025 | 5030 | ||
| 5026 | ;; Some predefined connection properties. | 5031 | ;; Some predefined connection properties. |
| 5027 | (defun tramp-get-inline-compress (vec prop size) | 5032 | (defun tramp-get-inline-compress (vec prop size) |