From 53b6a8b11383585ae8a175bf53964e35e889d338 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Mon, 17 Dec 2012 15:38:07 +0100 Subject: [PATCH] Add support for preserving ACL entries of files. * net/tramp.el (tramp-file-name-for-operation): Add `file-acl' and `set-file-acl' handlers. * net/tramp-adb.el (tramp-adb-handle-copy-file): Handle PRESERVE-EXTENDED-ATTRIBUTES. * net/tramp-compat.el (tramp-compat-copy-file): Handle PRESERVE-EXTENDED-ATTRIBUTES. * net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist): Add `file-acl' and `set-file-acl' handlers. (tramp-gvfs-handle-copy-file): Handle PRESERVE-EXTENDED-ATTRIBUTES. (tramp-gvfs-handle-file-acl, tramp-gvfs-handle-set-file-acl): New defuns. * net/tramp-sh.el (tramp-sh-file-name-handler-alist): Add `file-acl' and `set-file-acl' handlers. (tramp-remote-acl-p, tramp-sh-handle-file-acl) (tramp-sh-handle-set-file-acl): New defuns. (tramp-sh-handle-copy-file, tramp-do-copy-or-rename-file): Handle PRESERVE-EXTENDED-ATTRIBUTES. * net/tramp-smb.el (tramp-smb-file-name-handler-alist): Add `file-acl' and `set-file-acl' handlers. (tramp-smb-handle-copy-file): Handle PRESERVE-EXTENDED-ATTRIBUTES. --- lisp/ChangeLog | 31 ++++++++++++++++++++++ lisp/net/tramp-adb.el | 4 +-- lisp/net/tramp-compat.el | 9 ++++--- lisp/net/tramp-gvfs.el | 17 +++++++++--- lisp/net/tramp-sh.el | 56 +++++++++++++++++++++++++++++++++------- lisp/net/tramp-smb.el | 7 +++-- lisp/net/tramp.el | 3 ++- 7 files changed, 105 insertions(+), 22 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 21564f5daa5..26570fc7e90 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,34 @@ +2012-12-17 Michael Albinus + + Add support for preserving ACL entries of files. + + * net/tramp.el (tramp-file-name-for-operation): Add `file-acl' and + `set-file-acl' handlers. + + * net/tramp-adb.el (tramp-adb-handle-copy-file): Handle + PRESERVE-EXTENDED-ATTRIBUTES. + + * net/tramp-compat.el (tramp-compat-copy-file): Handle + PRESERVE-EXTENDED-ATTRIBUTES. + + * net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist): Add + `file-acl' and `set-file-acl' handlers. + (tramp-gvfs-handle-copy-file): Handle + PRESERVE-EXTENDED-ATTRIBUTES. + (tramp-gvfs-handle-file-acl, tramp-gvfs-handle-set-file-acl): New + defuns. + + * net/tramp-sh.el (tramp-sh-file-name-handler-alist): Add + `file-acl' and `set-file-acl' handlers. + (tramp-remote-acl-p, tramp-sh-handle-file-acl) + (tramp-sh-handle-set-file-acl): New defuns. + (tramp-sh-handle-copy-file, tramp-do-copy-or-rename-file): Handle + PRESERVE-EXTENDED-ATTRIBUTES. + + * net/tramp-smb.el (tramp-smb-file-name-handler-alist): Add + `file-acl' and `set-file-acl' handlers. + (tramp-smb-handle-copy-file): Handle PRESERVE-EXTENDED-ATTRIBUTES. + 2012-12-17 Kelly Dean (tiny change) * help-macro.el (make-help-screen): Instead of switch-to-buffer diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index d34980fe22e..261c65ffdae 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -526,9 +526,9 @@ But handle the case, if the \"test\" command is not available." (defun tramp-adb-handle-copy-file (filename newname &optional ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context) + preserve-uid-gid preserve-extended-attributes) "Like `copy-file' for Tramp files. -PRESERVE-UID-GID and PRESERVE-SELINUX-CONTEXT are completely ignored." +PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (setq filename (expand-file-name filename) newname (expand-file-name newname)) diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 3d37a0cfc39..5a322866693 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -304,16 +304,17 @@ Not actually used. Use `(format \"%o\" i)' instead?" (wrong-number-of-arguments (file-attributes filename)))))) ;; PRESERVE-UID-GID does not exist in XEmacs. -;; PRESERVE-SELINUX-CONTEXT has been introduced with Emacs 24.1. +;; PRESERVE-EXTENDED-ATTRIBUTES has been introduced with Emacs 24.1 +;; (as PRESERVE-SELINUX-CONTEXT), and renamed in Emacs 24.3. (defun tramp-compat-copy-file (filename newname &optional ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context) + preserve-uid-gid preserve-extended-attributes) "Like `copy-file' for Tramp files (compat function)." (cond - (preserve-selinux-context + (preserve-extended-attributes (tramp-compat-funcall 'copy-file filename newname ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context)) + preserve-uid-gid preserve-extended-attributes)) (preserve-uid-gid (tramp-compat-funcall 'copy-file filename newname ok-if-already-exists keep-date diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 1467aede2c3..be83e56d699 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -385,6 +385,7 @@ Every entry is a list (NAME ADDRESS).") ;; `executable-find' is not official yet. performed by default handler. (expand-file-name . tramp-gvfs-handle-expand-file-name) ;; `file-accessible-directory-p' performed by default handler. + (file-acl . tramp-gvfs-handle-file-acl) (file-attributes . tramp-gvfs-handle-file-attributes) (file-directory-p . tramp-gvfs-handle-file-directory-p) (file-executable-p . tramp-gvfs-handle-file-executable-p) @@ -417,6 +418,7 @@ Every entry is a list (NAME ADDRESS).") (make-symbolic-link . ignore) (process-file . tramp-gvfs-handle-process-file) (rename-file . tramp-gvfs-handle-rename-file) + (set-file-acl . tramp-gvfs-handle-set-file-acl) (set-file-modes . tramp-gvfs-handle-set-file-modes) (set-file-selinux-context . tramp-gvfs-handle-set-file-selinux-context) (set-visited-file-modtime . tramp-gvfs-handle-set-visited-file-modtime) @@ -539,7 +541,7 @@ is no information where to trace the message.") (defun tramp-gvfs-handle-copy-file (filename newname &optional ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context) + preserve-uid-gid preserve-extended-attributes) "Like `copy-file' for Tramp files." (with-parsed-tramp-file-name (if (tramp-tramp-file-p filename) filename newname) nil @@ -555,8 +557,8 @@ is no information where to trace the message.") (tramp-gvfs-fuse-file-name newname) newname) ok-if-already-exists keep-date preserve-uid-gid))) - (when preserve-selinux-context - (setq args (append args (list preserve-selinux-context)))) + (when preserve-extended-attributes + (setq args (append args (list preserve-extended-attributes)))) (apply 'copy-file args)) ;; Error case. Let's try it with the GVFS utilities. @@ -655,6 +657,10 @@ is no information where to trace the message.") (tramp-run-real-handler 'expand-file-name (list localname)))))) +(defun tramp-gvfs-handle-file-acl (filename) + "Like `file-acl' for Tramp files." + (tramp-compat-funcall 'file-acl (tramp-gvfs-fuse-file-name filename))) + (defun tramp-gvfs-handle-file-attributes (filename &optional id-format) "Like `file-attributes' for Tramp files." (file-attributes (tramp-gvfs-fuse-file-name filename) id-format)) @@ -781,6 +787,11 @@ is no information where to trace the message.") (tramp-flush-file-property v (file-name-directory localname)) (tramp-flush-file-property v localname)))) +(defun tramp-gvfs-handle-set-file-acl (filename acl-string) + "Like `set-file-acl' for Tramp files." + (with-tramp-gvfs-error-message filename 'set-file-acl + (tramp-gvfs-fuse-file-name filename) acl-string)) + (defun tramp-gvfs-handle-set-file-modes (filename mode) "Like `set-file-modes' for Tramp files." (with-tramp-gvfs-error-message filename 'set-file-modes diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 3008601d9ca..788246bffd5 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -985,6 +985,8 @@ This is used to map a mode number to a permission string.") (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime) (file-selinux-context . tramp-sh-handle-file-selinux-context) (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context) + (file-acl . tramp-sh-handle-file-acl) + (set-file-acl . tramp-sh-handle-set-file-acl) (vc-registered . tramp-sh-handle-vc-registered)) "Alist of handler functions. Operations not mentioned here will be handled by the normal Emacs functions.") @@ -1532,6 +1534,39 @@ and gid of the corresponding user is taken. Both parameters must be integers." ;; We always return nil. nil) +(defun tramp-remote-acl-p (vec) + "Check, whether ACL is enabled on the remote host." + (with-tramp-connection-property (tramp-get-connection-process vec) "acl-p" + (tramp-send-command-and-check vec "getfacl /"))) + +(defun tramp-sh-handle-file-acl (filename) + "Like `file-acl' for Tramp files." + (with-parsed-tramp-file-name filename nil + (with-tramp-file-property v localname "file-acl" + (when (and (tramp-remote-acl-p v) + (tramp-send-command-and-check + v (format + "getfacl -ac %s 2>/dev/null" + (tramp-shell-quote-argument localname)))) + (with-current-buffer (tramp-get-connection-buffer v) + (buffer-string)))))) + +(defun tramp-sh-handle-set-file-acl (filename acl-string) + "Like `set-file-acl' for Tramp files." + (with-parsed-tramp-file-name filename nil + (if (and (stringp acl-string) + (tramp-remote-acl-p v) + (tramp-send-command-and-check + v + (format "setfacl --set-file=- %s <<'EOF'\n%s\nEOF\n" + (tramp-shell-quote-argument localname) + acl-string) + t)) + (tramp-set-file-property v localname "file-acl" acl-string) + (tramp-set-file-property v localname "file-acl-string" 'undef))) + ;; We always return nil. + nil) + ;; Simple functions using the `test' command. (defun tramp-sh-handle-file-executable-p (filename) @@ -1883,7 +1918,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" (defun tramp-sh-handle-copy-file (filename newname &optional ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context) + preserve-uid-gid preserve-extended-attributes) "Like `copy-file' for Tramp files." (setq filename (expand-file-name filename)) (setq newname (expand-file-name newname)) @@ -1893,13 +1928,13 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" (tramp-tramp-file-p newname)) (tramp-do-copy-or-rename-file 'copy filename newname ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context)) + preserve-uid-gid preserve-extended-attributes)) ;; Compat section. - (preserve-selinux-context + (preserve-extended-attributes (tramp-run-real-handler 'copy-file (list filename newname ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context))) + preserve-uid-gid preserve-extended-attributes))) (preserve-uid-gid (tramp-run-real-handler 'copy-file @@ -1962,7 +1997,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" (defun tramp-do-copy-or-rename-file (op filename newname &optional ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context) + preserve-uid-gid preserve-extended-attributes) "Copy or rename a remote file. OP must be `copy' or `rename' and indicates the operation to perform. FILENAME specifies the file to copy or rename, NEWNAME is the name of @@ -1971,7 +2006,7 @@ OK-IF-ALREADY-EXISTS means don't barf if NEWNAME exists already. KEEP-DATE means to make sure that NEWNAME has the same timestamp as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep the uid and gid if both files are on the same host. -PRESERVE-SELINUX-CONTEXT activates selinux commands. +PRESERVE-EXTENDED-ATTRIBUTES activates selinux and acl commands. This function is invoked by `tramp-sh-handle-copy-file' and `tramp-sh-handle-rename-file'. It is an error if OP is neither @@ -1982,8 +2017,8 @@ file names." (let ((t1 (tramp-tramp-file-p filename)) (t2 (tramp-tramp-file-p newname)) (length (nth 7 (file-attributes (file-truename filename)))) - (context (and preserve-selinux-context - (apply 'file-selinux-context (list filename)))) + (attributes (and preserve-extended-attributes + (apply 'file-extended-attributes (list filename)))) pr tm) (with-parsed-tramp-file-name (if t1 filename newname) nil @@ -2053,8 +2088,9 @@ file names." ;; One of them must be a Tramp file. (error "Tramp implementation says this cannot happen"))) - ;; Handle `preserve-selinux-context'. - (when context (apply 'set-file-selinux-context (list newname context))) + ;; Handle `preserve-extended-attributes'. + (when attributes + (apply 'set-file-extended-attributes (list newname attributes))) ;; In case of `rename', we must flush the cache of the source file. (when (and t1 (eq op 'rename)) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index d4386a5374c..f97d4620b97 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -195,6 +195,7 @@ See `tramp-actions-before-shell' for more info.") (dired-uncache . tramp-handle-dired-uncache) (expand-file-name . tramp-smb-handle-expand-file-name) (file-accessible-directory-p . tramp-smb-handle-file-directory-p) + (file-acl . ignore) (file-attributes . tramp-smb-handle-file-attributes) (file-directory-p . tramp-smb-handle-file-directory-p) (file-executable-p . tramp-handle-file-exists-p) @@ -227,6 +228,7 @@ See `tramp-actions-before-shell' for more info.") (make-symbolic-link . tramp-smb-handle-make-symbolic-link) (process-file . tramp-smb-handle-process-file) (rename-file . tramp-smb-handle-rename-file) + (set-file-acl . ignore) (set-file-modes . tramp-smb-handle-set-file-modes) ;; `set-file-selinux-context' performed by default handler. (set-file-times . ignore) @@ -487,10 +489,10 @@ pass to the OPERATION." (defun tramp-smb-handle-copy-file (filename newname &optional ok-if-already-exists keep-date - preserve-uid-gid preserve-selinux-context) + preserve-uid-gid preserve-extended-attributes) "Like `copy-file' for Tramp files. KEEP-DATE has no effect in case NEWNAME resides on an SMB server. -PRESERVE-UID-GID and PRESERVE-SELINUX-CONTEXT are completely ignored." +PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (setq filename (expand-file-name filename) newname (expand-file-name newname)) (with-tramp-progress-reporter @@ -1813,5 +1815,6 @@ Returns nil if an error message has appeared." ;; * Try to remove the inclusion of dummy "" directory. Seems to be at ;; several places, especially in `tramp-smb-handle-insert-directory'. ;; * Ignore case in file names. +;; * Implement `tramp-smb-handle-file-acl' for proper Samba versions. ;;; tramp-smb.el ends here diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index a4d36cbe72c..a4be6eab41f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1879,7 +1879,8 @@ ARGS are the arguments OPERATION has been called with." ;; Emacs 22+ only. 'set-file-times ;; Emacs 24+ only. - 'file-selinux-context 'set-file-selinux-context + 'file-acl 'file-selinux-context + 'set-file-acl 'set-file-selinux-context ;; XEmacs only. 'abbreviate-file-name 'create-file-buffer 'dired-file-modtime 'dired-make-compressed-filename -- 2.39.2