[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 588a0363d9a: Improve SELinux handling in Tramp
From: |
Michael Albinus |
Subject: |
master 588a0363d9a: Improve SELinux handling in Tramp |
Date: |
Thu, 3 Aug 2023 07:17:14 -0400 (EDT) |
branch: master
commit 588a0363d9a3ce6d678618ad545f7a8f9af27880
Author: Michael Albinus <michael.albinus@gmx.de>
Commit: Michael Albinus <michael.albinus@gmx.de>
Improve SELinux handling in Tramp
* lisp/net/tramp-sh.el (tramp-stat-file-attributes-with-selinux)
(tramp-stat-directory-files-and-attributes-with-selinux): New defconst.
(tramp-do-file-attributes-with-ls)
(tramp-do-file-attributes-with-stat)
(tramp-do-directory-files-and-attributes-with-stat): Return also
SELinux context.
(tramp-remote-selinux-p, tramp-do-copy-or-rename-file): Adapt docstring.
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file)
(tramp-sudoedit-remote-selinux-p): Adapt docstring.
(tramp-sudoedit-file-attributes-with-selinux): New defconst.
(tramp-sudoedit-handle-file-attributes): Use it.
* lisp/net/tramp.el (tramp-convert-file-attributes):
Extract SELinux context.
---
lisp/net/tramp-sh.el | 108 +++++++++++++++++++++++++++++++++++++--------
lisp/net/tramp-sudoedit.el | 33 +++++++++++---
lisp/net/tramp.el | 7 +++
3 files changed, 125 insertions(+), 23 deletions(-)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index b33e788b893..2b1d26dd232 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -717,6 +717,25 @@ on the remote file system.
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
+(defconst tramp-stat-file-attributes-with-selinux
+ (format
+ (concat
+ "(%%s -c"
+ " '((%s%%%%N%s) %%%%h (%s%%%%U%s . %%%%u) (%s%%%%G%s . %%%%g)"
+ " %%%%X %%%%Y %%%%Z %%%%s %s%%%%A%s t %%%%i -1 %s%%%%C%s)'"
+ " \"$1\" %%n || echo nil) |"
+ " sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'")
+ tramp-stat-marker tramp-stat-marker ; %%N
+ tramp-stat-marker tramp-stat-marker ; %%U
+ tramp-stat-marker tramp-stat-marker ; %%G
+ tramp-stat-marker tramp-stat-marker ; %%A
+ tramp-stat-marker tramp-stat-marker ; %%C
+ tramp-stat-quoted-marker)
+ "Shell function to produce output suitable for use with `file-attributes'
+on the remote file system, including SELinux context.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
+
(defconst tramp-perl-directory-files-and-attributes
"%p -e '
chdir($ARGV[0]) or printf(\"\\\"Cannot change to $ARGV[0]: $''!''\\\"\\n\"),
exit();
@@ -795,6 +814,33 @@ characters need to be doubled.")
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
+(defconst tramp-stat-directory-files-and-attributes-with-selinux
+ (format
+ (concat
+ ;; We must care about file names with spaces, or starting with
+ ;; "-"; this would confuse xargs. "ls -aQ" might be a solution,
+ ;; but it does not work on all remote systems. Therefore, we use
+ ;; \000 as file separator. `tramp-sh--quoting-style-options' do
+ ;; not work for file names with spaces piped to "xargs".
+ ;; Apostrophes in the stat output are masked as
+ ;; `tramp-stat-marker', in order to make a proper shell escape of
+ ;; them in file names.
+ "cd \"$1\" && echo \"(\"; (%%l -a | tr '\\n\\r' '\\000\\000' |"
+ " xargs -0 %%s -c"
+ " '(%s%%%%n%s (%s%%%%N%s) %%%%h (%s%%%%U%s . %%%%u) (%s%%%%G%s . %%%%g)
%%%%X %%%%Y %%%%Z %%%%s %s%%%%A%s t %%%%i -1 %s%%%%C%s)'"
+ " -- %%n | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"")
+ tramp-stat-marker tramp-stat-marker ; %n
+ tramp-stat-marker tramp-stat-marker ; %N
+ tramp-stat-marker tramp-stat-marker ; %U
+ tramp-stat-marker tramp-stat-marker ; %G
+ tramp-stat-marker tramp-stat-marker ; %A
+ tramp-stat-marker tramp-stat-marker ; %C
+ tramp-stat-quoted-marker)
+ "Shell function implementing `directory-files-and-attributes' as Lisp
+`read'able output, including SELinux context.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
+
(defconst tramp-perl-id
"%p -e '
use strict;
@@ -1255,10 +1301,10 @@ Operations not mentioned here will be handled by the
normal Emacs functions.")
(let (symlinkp dirp
res-inode res-filemodes res-numlinks
res-uid-string res-gid-string res-uid-integer res-gid-integer
- res-size res-symlink-target)
+ res-size res-symlink-target res-context)
(tramp-message vec 5 "file attributes with ls: %s" localname)
- ;; We cannot send all three commands combined, it could exceed
- ;; NAME_MAX or PATH_MAX. Happened on macOS, for example.
+ ;; We cannot send both commands combined, it could exceed NAME_MAX
+ ;; or PATH_MAX. Happened on macOS, for example.
(when (tramp-send-command-and-check
vec
(format "cd %s && (%s %s || %s -h %s)"
@@ -1277,13 +1323,14 @@ Operations not mentioned here will be handled by the
normal Emacs functions.")
(file-name-nondirectory localname)))))
(tramp-send-command
vec
- (format "%s -ild %s %s; %s -lnd %s %s"
+ (format "%s -ild %s %s; %s -lnd%s %s %s"
(tramp-get-ls-command vec)
;; On systems which have no quoting style, file names
;; with special characters could fail.
(tramp-sh--quoting-style-options vec)
(tramp-shell-quote-argument localname)
(tramp-get-ls-command vec)
+ (if (tramp-remote-selinux-p vec) "Z" "")
;; On systems which have no quoting style, file names
;; with special characters could fail.
(tramp-sh--quoting-style-options vec)
@@ -1333,6 +1380,10 @@ Operations not mentioned here will be handled by the
normal Emacs functions.")
(setq res-uid-integer tramp-unknown-id-integer))
(unless (numberp res-gid-integer)
(setq res-gid-integer tramp-unknown-id-integer))
+ ;; ... SELinux context
+ (when (tramp-remote-selinux-p vec)
+ (setq res-context (read (current-buffer))
+ res-context (symbol-name res-context)))
;; Return data gathered.
(list
@@ -1359,7 +1410,10 @@ Operations not mentioned here will be handled by the
normal Emacs functions.")
;; 10. Inode number.
res-inode
;; 11. Device number. Will be replaced by a virtual device number.
- -1))))))
+ -1
+ ;; 12. SELinux context. Will be extracted in
+ ;; `tramp-convert-file-attributes'.
+ res-context))))))
(defun tramp-do-file-attributes-with-perl (vec localname)
"Implement `file-attributes' for Tramp files using a Perl script."
@@ -1373,11 +1427,20 @@ Operations not mentioned here will be handled by the
normal Emacs functions.")
(defun tramp-do-file-attributes-with-stat (vec localname)
"Implement `file-attributes' for Tramp files using stat(1) command."
(tramp-message vec 5 "file attributes with stat: %s" localname)
- (tramp-maybe-send-script
- vec tramp-stat-file-attributes "tramp_stat_file_attributes")
- (tramp-send-command-and-read
- vec (format "tramp_stat_file_attributes %s"
- (tramp-shell-quote-argument localname))))
+ (cond
+ ((tramp-remote-selinux-p vec)
+ (tramp-maybe-send-script
+ vec tramp-stat-file-attributes-with-selinux
+ "tramp_stat_file_attributes_with_selinux")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_file_attributes_with_selinux %s"
+ (tramp-shell-quote-argument localname))))
+ (t
+ (tramp-maybe-send-script
+ vec tramp-stat-file-attributes "tramp_stat_file_attributes")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_file_attributes %s"
+ (tramp-shell-quote-argument localname))))))
(defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
"Like `set-visited-file-modtime' for Tramp files."
@@ -1572,7 +1635,7 @@ ID-FORMAT valid values are `string' and `integer'."
(tramp-shell-quote-argument localname))))))))
(defun tramp-remote-selinux-p (vec)
- "Check, whether SELINUX is enabled on the remote host."
+ "Check, whether SELinux is enabled on the remote host."
(with-tramp-connection-property (tramp-get-process vec) "selinux-p"
(tramp-send-command-and-check vec "selinuxenabled")))
@@ -1775,12 +1838,21 @@ ID-FORMAT valid values are `string' and `integer'."
(defun tramp-do-directory-files-and-attributes-with-stat (vec localname)
"Implement `directory-files-and-attributes' for Tramp files with stat(1)
command."
(tramp-message vec 5 "directory-files-and-attributes with stat: %s"
localname)
- (tramp-maybe-send-script
- vec tramp-stat-directory-files-and-attributes
- "tramp_stat_directory_files_and_attributes")
- (tramp-send-command-and-read
- vec (format "tramp_stat_directory_files_and_attributes %s"
- (tramp-shell-quote-argument localname))))
+ (cond
+ ((tramp-remote-selinux-p vec)
+ (tramp-maybe-send-script
+ vec tramp-stat-directory-files-and-attributes-with-selinux
+ "tramp_stat_directory_files_and_attributes_with_selinux")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_directory_files_and_attributes_with_selinux %s"
+ (tramp-shell-quote-argument localname))))
+ (t
+ (tramp-maybe-send-script
+ vec tramp-stat-directory-files-and-attributes
+ "tramp_stat_directory_files_and_attributes")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_directory_files_and_attributes %s"
+ (tramp-shell-quote-argument localname))))))
;; This function should return "foo/" for directories and "bar" for
;; files.
@@ -1966,7 +2038,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-EXTENDED-ATTRIBUTES activates selinux and acl 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
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index 2ce2647b5ac..3d6e1d92d0b 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -234,7 +234,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-EXTENDED-ATTRIBUTES activates selinux and acl commands.
+PRESERVE-EXTENDED-ATTRIBUTES activates SELinux and ACL commands.
This function is invoked by `tramp-sudoedit-handle-copy-file' and
`tramp-sudoedit-handle-rename-file'. It is an error if OP is
@@ -434,14 +434,37 @@ the result will be a local, non-Tramp, file name."
"stat format string to produce output suitable for use with
`file-attributes' on the remote file system.")
+(defconst tramp-sudoedit-file-attributes-with-selinux
+ (format
+ ;; Apostrophes in the stat output are masked as
+ ;; `tramp-stat-marker', in order to make a proper shell escape of
+ ;; them in file names. They are replaced in
+ ;; `tramp-sudoedit-send-command-and-read'.
+ (concat "((%s%%N%s) %%h (%s%%U%s . %%u) (%s%%G%s . %%g)"
+ " %%X %%Y %%Z %%s %s%%A%s t %%i -1 %s%%C%s)")
+ tramp-stat-marker tramp-stat-marker ; %%N
+ tramp-stat-marker tramp-stat-marker ; %%U
+ tramp-stat-marker tramp-stat-marker ; %%G
+ tramp-stat-marker tramp-stat-marker ; %%A
+ tramp-stat-marker tramp-stat-marker) ; %%C
+ "stat format string to produce output suitable for use with
+`file-attributes' on the remote file system, including SELinux context.")
+
(defun tramp-sudoedit-handle-file-attributes (filename &optional id-format)
"Like `file-attributes' for Tramp files."
;; The result is cached in `tramp-convert-file-attributes'.
(with-parsed-tramp-file-name (expand-file-name filename) nil
(tramp-convert-file-attributes v localname id-format
- (tramp-sudoedit-send-command-and-read
- v "env" "QUOTING_STYLE=locale" "stat" "-c"
- tramp-sudoedit-file-attributes (file-name-unquote localname)))))
+ (cond
+ ((tramp-sudoedit-remote-selinux-p v)
+ (tramp-sudoedit-send-command-and-read
+ v "env" "QUOTING_STYLE=locale" "stat" "-c"
+ tramp-sudoedit-file-attributes-with-selinux
+ (file-name-unquote localname)))
+ (t
+ (tramp-sudoedit-send-command-and-read
+ v "env" "QUOTING_STYLE=locale" "stat" "-c"
+ tramp-sudoedit-file-attributes (file-name-unquote localname)))))))
(defun tramp-sudoedit-handle-file-executable-p (filename)
"Like `file-executable-p' for Tramp files."
@@ -507,7 +530,7 @@ the result will be a local, non-Tramp, file name."
v 'file-error "Error while changing file's mode %s" filename)))))
(defun tramp-sudoedit-remote-selinux-p (vec)
- "Check, whether SELINUX is enabled on the remote host."
+ "Check, whether SELinux is enabled on the remote host."
(with-tramp-connection-property (tramp-get-process vec) "selinux-p"
(zerop (tramp-call-process vec "selinuxenabled"))))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 0267b69340d..31b91b4e910 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -6055,6 +6055,13 @@ to cache the result. Return the modified ATTR."
;; Set virtual device number.
(setcar (nthcdr 11 attr)
(tramp-get-device ,vec))
+ ;; Set SELinux context.
+ (when (stringp (nth 12 attr))
+ (tramp-set-file-property
+ ,vec ,localname "file-selinux-context"
+ (split-string (nth 12 attr) ":" 'omit)))
+ ;; Remove optional entries.
+ (setcdr (nthcdr 11 attr) nil)
attr)))))
;; Return normalized result.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 588a0363d9a: Improve SELinux handling in Tramp,
Michael Albinus <=