From 12c3461b455bf06551060ed6061f7df84967ae97 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Tue, 16 Aug 2022 19:41:00 +0200 Subject: [PATCH] Handle root permissions on remote files * lisp/net/tramp.el (tramp-check-cached-permissions): Check also for remote uid/gid being 0. (Bug#57238) * lisp/net/tramp-sh.el (tramp-do-file-attributes-with-ls): Convert numeric uid/gid strings into real strings. (tramp-sh-get-signal-strings): Use `zerop'. * lisp/net/tramp.el (tramp-root-id-string, tramp-root-id-integer): New defconsts. (tramp-handle-find-backup-file-name, tramp-handle-lock-file) (tramp-local-host-p, tramp-handle-make-auto-save-file-name) * lisp/net/tramp-sh.el (tramp-default-method-alist) (ramp-default-user-alist, tramp-find-shell): * lisp/net/tramp-sudoedit.el (tramp-default-user-alist): Use them. --- lisp/net/tramp-sh.el | 17 ++++++++++++----- lisp/net/tramp-sudoedit.el | 3 ++- lisp/net/tramp.el | 35 +++++++++++++++++++++++------------ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index f2e3c48235a..4a9cf2e6997 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -410,11 +410,12 @@ The string is used in `tramp-methods'.") (tramp-copy-keep-date t))) (add-to-list 'tramp-default-method-alist - `(,tramp-local-host-regexp "\\`root\\'" "su")) + `(,tramp-local-host-regexp + ,(format "\\`%s\\'" tramp-root-id-string) "su")) (add-to-list 'tramp-default-user-alist `(,(concat "\\`" (regexp-opt '("su" "sudo" "doas" "ksu")) "\\'") - nil "root")) + nil ,tramp-root-id-string)) ;; Do not add "ssh" based methods, otherwise ~/.ssh/config would be ignored. ;; Do not add "plink" based methods, they ask interactively for the user. (add-to-list 'tramp-default-user-alist @@ -1314,8 +1315,12 @@ component is used as the target of the symlink." ;; ... uid and gid (setq res-uid-string (read (current-buffer))) (setq res-gid-string (read (current-buffer))) + (when (natnump res-uid-string) + (setq res-uid-string (number-to-string res-uid-string))) (unless (stringp res-uid-string) (setq res-uid-string (symbol-name res-uid-string))) + (when (natnump res-gid-string) + (setq res-gid-string (number-to-string res-gid-string))) (unless (stringp res-gid-string) (setq res-gid-string (symbol-name res-gid-string))) ;; ... size @@ -3096,7 +3101,7 @@ implementation will be used." (cond ;; Some predefined values, which aren't reported sometimes, ;; or would raise problems (all Stopped signals). - ((= i 0) 0) + ((zerop i) 0) ((string-equal (nth i signals) "HUP") "Hangup") ((string-equal (nth i signals) "INT") "Interrupt") ((string-equal (nth i signals) "QUIT") "Quit") @@ -4272,8 +4277,10 @@ file exists and nonzero exit status otherwise." (with-tramp-connection-property vec "remote-shell" ;; CCC: "root" does not exist always, see my QNAP ;; TS-459. Which check could we apply instead? - (tramp-send-command vec "echo ~root" t) - (if (or (string-match-p "^~root$" (buffer-string)) + (tramp-send-command + vec (format "echo ~%s" tramp-root-id-string) t) + (if (or (string-match-p + (format "^~%s$" tramp-root-id-string) (buffer-string)) ;; The default shell (ksh93) of OpenSolaris ;; and Solaris is buggy. We've got reports ;; for "SunOS 5.10" and "SunOS 5.11" so far. diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 3564a1b7b44..0de2e0ef69a 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -48,7 +48,8 @@ ("-p" "Password:") ("--"))) (tramp-password-previous-hop t))) - (add-to-list 'tramp-default-user-alist '("\\`sudoedit\\'" nil "root")) + (add-to-list 'tramp-default-user-alist + `("\\`sudoedit\\'" nil ,tramp-root-id-string)) (tramp-set-completion-function tramp-sudoedit-method tramp-completion-function-alist-su)) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 5ffc4f1b88b..046d814547f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1055,6 +1055,12 @@ Derived from `tramp-postfix-host-format'.") (defconst tramp-unknown-id-integer -1 "Integer used to denote an unknown user or group.") +(defconst tramp-root-id-string "root" + "String used to denote the root user or group.") + +(defconst tramp-root-id-integer 0 + "Integer used to denote the root user or group.") + ;;; File name format: (defun tramp-build-remote-file-name-spec-regexp () @@ -4097,9 +4103,10 @@ Let-bind it when necessary.") (when (and (not tramp-allow-unsafe-temporary-files) (not backup-inhibited) (file-in-directory-p (car result) temporary-file-directory) - (zerop (or (file-attribute-user-id - (file-attributes filename 'integer)) - tramp-unknown-id-integer)) + (= (or (file-attribute-user-id + (file-attributes filename 'integer)) + tramp-unknown-id-integer) + tramp-root-id-integer) (not (with-tramp-connection-property (tramp-get-process v) "unsafe-temporary-file" (yes-or-no-p @@ -4482,9 +4489,10 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.") (when (and (not tramp-allow-unsafe-temporary-files) create-lockfiles (file-in-directory-p lockname temporary-file-directory) - (zerop (or (file-attribute-user-id - (file-attributes file 'integer)) - tramp-unknown-id-integer)) + (= (or (file-attribute-user-id + (file-attributes file 'integer)) + tramp-unknown-id-integer) + tramp-root-id-integer) (not (with-tramp-connection-property (tramp-get-process v) "unsafe-temporary-file" (yes-or-no-p @@ -5840,14 +5848,16 @@ be granted." ;; User accessible and owned by user. (and (eq access (aref (file-attribute-modes file-attr) offset)) - (or (equal remote-uid tramp-unknown-id-integer) + (or (equal remote-uid tramp-root-id-integer) + (equal remote-uid tramp-unknown-id-integer) (equal remote-uid (file-attribute-user-id file-attr)) (equal tramp-unknown-id-integer (file-attribute-user-id file-attr)))) ;; Group accessible and owned by user's principal group. (and (eq access (aref (file-attribute-modes file-attr) (+ offset 3))) - (or (equal remote-gid tramp-unknown-id-integer) + (or (equal remote-gid tramp-root-id-integer) + (equal remote-gid tramp-unknown-id-integer) (equal remote-gid (file-attribute-group-id file-attr)) (equal tramp-unknown-id-integer (file-attribute-group-id file-attr))))))) @@ -6007,7 +6017,7 @@ This handles also chrooted environments, which are not regarded as local." (tramp-make-tramp-file-name vec tramp-compat-temporary-file-directory)) ;; On some systems, chown runs only for root. (or (zerop (user-uid)) - (zerop (tramp-get-remote-uid vec 'integer)))))) + (= (tramp-get-remote-uid vec 'integer) tramp-root-id-integer))))) (defun tramp-get-remote-tmpdir (vec) "Return directory for temporary files on the remote host identified by VEC." @@ -6093,9 +6103,10 @@ this file, if that variable is non-nil." (when (and (not tramp-allow-unsafe-temporary-files) auto-save-default (file-in-directory-p result temporary-file-directory) - (zerop (or (file-attribute-user-id - (file-attributes filename 'integer)) - tramp-unknown-id-integer)) + (= (or (file-attribute-user-id + (file-attributes filename 'integer)) + tramp-unknown-id-integer) + tramp-root-id-integer) (not (with-tramp-connection-property (tramp-get-process v) "unsafe-temporary-file" (yes-or-no-p -- 2.39.2