diff options
| author | Jim Porter | 2023-05-01 09:49:00 -0700 |
|---|---|---|
| committer | Jim Porter | 2023-05-02 21:28:34 -0700 |
| commit | 40d66095635ead025b33dc693a19b463f70eb9ce (patch) | |
| tree | 75459d0d63878ddda41018cba4bc9dad0b6136bc /lisp/eshell | |
| parent | fa33a14ebe56aa1726df9c8ad93106966c5b6eae (diff) | |
| download | emacs-40d66095635ead025b33dc693a19b463f70eb9ce.tar.gz emacs-40d66095635ead025b33dc693a19b463f70eb9ce.zip | |
Use connection-aware functions when getting the UID/GID in Eshell
This means, for example, that when using Tramp to sudo in Eshell, "rm"
queries the user before deleting anything (bug#63221).
* lisp/eshell/esh-util.el (eshell-user-login-name): New function...
* lisp/eshell/em-unix.el (eshell/whoami): ... use it.
* lisp/eshell/em-ls.el (eshell-ls-applicable): Use 'file-user-uid' and
'eshell-user-login-name'.
(eshell-ls-decorated-name): Use 'file-user-uid'.
* lisp/eshell/em-pred.el (eshell-predicate-alist): Use 'file-user-uid'
and 'file-group-gid'.
* lisp/eshell/em-unix.el (eshell-interactive-query): New widget...
(eshell-rm-interactive-query, eshell-mv-interactive-query)
(eshell-cp-interactive-query, eshell-ln-interactive-query): ... use
it.
(eshell-interactive-query-p): New function...
(eshell/rm, eshell/mv, eshell/cp, eshell/ln): ... use it.
* lisp/simple.el (file-group-gid): New function.
* lisp/net/ange-ftp.el (ange-ftp-file-group-gid): New function...
(file-group-gid): ... use it.
* lisp/net/tramp.el (tramp-handle-file-group-gid):
* lisp/net/tramp-archive.el (tramp-archive-handle-file-group-gid): New
functions.
* lisp/net/tramp.el (tramp-file-name-for-operation): Add
'file-group-gid'.
* lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
* lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist):
* lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
* lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
* lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
* lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
* lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist):
* lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
Add 'file-group-gid' mapping.
* test/lisp/net/tramp-tests.el (tramp-test44-file-user-group-ids):
* test/lisp/net/tramp-archive-tests.el
(tramp-archive-test44-file-user-group-ids): Add tests for
'file-group-gid'.
* doc/lispref/files.texi (Magic File Names): Mention 'file-group-gid'.
* doc/lispref/os.texi (User Identification): Document
'file-group-gid', and move 'group-real-gid' to match the order of
'user-real-uid'.
* etc/NEWS: Announce 'file-group-gid'.
Diffstat (limited to 'lisp/eshell')
| -rw-r--r-- | lisp/eshell/em-ls.el | 6 | ||||
| -rw-r--r-- | lisp/eshell/em-pred.el | 4 | ||||
| -rw-r--r-- | lisp/eshell/em-unix.el | 70 | ||||
| -rw-r--r-- | lisp/eshell/esh-util.el | 5 |
4 files changed, 63 insertions, 22 deletions
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el index 56c5f262789..9b53bf29559 100644 --- a/lisp/eshell/em-ls.el +++ b/lisp/eshell/em-ls.el | |||
| @@ -199,9 +199,9 @@ calling FUNC with FILE as an argument." | |||
| 199 | `(let ((owner (file-attribute-user-id ,attrs)) | 199 | `(let ((owner (file-attribute-user-id ,attrs)) |
| 200 | (modes (file-attribute-modes ,attrs))) | 200 | (modes (file-attribute-modes ,attrs))) |
| 201 | (cond ((cond ((numberp owner) | 201 | (cond ((cond ((numberp owner) |
| 202 | (= owner (user-uid))) | 202 | (= owner (file-user-uid))) |
| 203 | ((stringp owner) | 203 | ((stringp owner) |
| 204 | (or (string-equal owner (user-login-name)) | 204 | (or (string-equal owner (eshell-user-login-name)) |
| 205 | (member owner (eshell-current-ange-uids))))) | 205 | (member owner (eshell-current-ange-uids))))) |
| 206 | ;; The user owns this file. | 206 | ;; The user owns this file. |
| 207 | (not (eq (aref modes ,index) ?-))) | 207 | (not (eq (aref modes ,index) ?-))) |
| @@ -919,7 +919,7 @@ to use, and each member of which is the width of that column | |||
| 919 | ((not (eshell-ls-filetype-p (cdr file) ?-)) | 919 | ((not (eshell-ls-filetype-p (cdr file) ?-)) |
| 920 | 'eshell-ls-special) | 920 | 'eshell-ls-special) |
| 921 | 921 | ||
| 922 | ((and (/= (user-uid) 0) ; root can execute anything | 922 | ((and (/= (file-user-uid) 0) ; root can execute anything |
| 923 | (eshell-ls-applicable (cdr file) 3 | 923 | (eshell-ls-applicable (cdr file) 3 |
| 924 | 'file-executable-p (car file))) | 924 | 'file-executable-p (car file))) |
| 925 | 'eshell-ls-executable) | 925 | 'eshell-ls-executable) |
diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el index 2ccca092b86..bfb0dad60ef 100644 --- a/lisp/eshell/em-pred.el +++ b/lisp/eshell/em-pred.el | |||
| @@ -87,11 +87,11 @@ ordinary strings." | |||
| 87 | (?U . (lambda (file) ; owned by effective uid | 87 | (?U . (lambda (file) ; owned by effective uid |
| 88 | (if (file-exists-p file) | 88 | (if (file-exists-p file) |
| 89 | (= (file-attribute-user-id (file-attributes file)) | 89 | (= (file-attribute-user-id (file-attributes file)) |
| 90 | (user-uid))))) | 90 | (file-user-uid))))) |
| 91 | (?G . (lambda (file) ; owned by effective gid | 91 | (?G . (lambda (file) ; owned by effective gid |
| 92 | (if (file-exists-p file) | 92 | (if (file-exists-p file) |
| 93 | (= (file-attribute-group-id (file-attributes file)) | 93 | (= (file-attribute-group-id (file-attributes file)) |
| 94 | (group-gid))))) | 94 | (file-group-gid))))) |
| 95 | (?* . (lambda (file) | 95 | (?* . (lambda (file) |
| 96 | (and (file-regular-p file) | 96 | (and (file-regular-p file) |
| 97 | (not (file-symlink-p file)) | 97 | (not (file-symlink-p file)) |
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index a792493e071..b7ef0f0c40c 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el | |||
| @@ -91,14 +91,29 @@ Otherwise, `rmdir' is required." | |||
| 91 | :type 'boolean | 91 | :type 'boolean |
| 92 | :group 'eshell-unix) | 92 | :group 'eshell-unix) |
| 93 | 93 | ||
| 94 | (defcustom eshell-rm-interactive-query (= (user-uid) 0) | 94 | (define-widget 'eshell-interactive-query 'radio |
| 95 | "If non-nil, `rm' will query before removing anything." | 95 | "When to interatively query the user about a particular operation. |
| 96 | :type 'boolean | 96 | If t, always query. If nil, never query. If `root', query when |
| 97 | the user is logged in as root (including when `default-directory' | ||
| 98 | is remote with a root user)." | ||
| 99 | :args '((const :tag "Never" nil) | ||
| 100 | (const :tag "Always" t) | ||
| 101 | (const :tag "When root" root))) | ||
| 102 | |||
| 103 | (defcustom eshell-rm-interactive-query 'root | ||
| 104 | "When `rm' should query before removing anything. | ||
| 105 | If t, always query. If nil, never query. If `root', query when | ||
| 106 | the user is logged in as root (including when `default-directory' | ||
| 107 | is remote with a root user)." | ||
| 108 | :type 'eshell-interactive-query | ||
| 97 | :group 'eshell-unix) | 109 | :group 'eshell-unix) |
| 98 | 110 | ||
| 99 | (defcustom eshell-mv-interactive-query (= (user-uid) 0) | 111 | (defcustom eshell-mv-interactive-query 'root |
| 100 | "If non-nil, `mv' will query before overwriting anything." | 112 | "When `mv' should query before overwriting anything. |
| 101 | :type 'boolean | 113 | If t, always query. If nil, never query. If `root', query when |
| 114 | the user is logged in as root (including when `default-directory' | ||
| 115 | is remote with a root user)." | ||
| 116 | :type 'eshell-interactive-query | ||
| 102 | :group 'eshell-unix) | 117 | :group 'eshell-unix) |
| 103 | 118 | ||
| 104 | (defcustom eshell-mv-overwrite-files t | 119 | (defcustom eshell-mv-overwrite-files t |
| @@ -106,9 +121,12 @@ Otherwise, `rmdir' is required." | |||
| 106 | :type 'boolean | 121 | :type 'boolean |
| 107 | :group 'eshell-unix) | 122 | :group 'eshell-unix) |
| 108 | 123 | ||
| 109 | (defcustom eshell-cp-interactive-query (= (user-uid) 0) | 124 | (defcustom eshell-cp-interactive-query 'root |
| 110 | "If non-nil, `cp' will query before overwriting anything." | 125 | "When `cp' should query before overwriting anything. |
| 111 | :type 'boolean | 126 | If t, always query. If nil, never query. If `root', query when |
| 127 | the user is logged in as root (including when `default-directory' | ||
| 128 | is remote with a root user)." | ||
| 129 | :type 'eshell-interactive-query | ||
| 112 | :group 'eshell-unix) | 130 | :group 'eshell-unix) |
| 113 | 131 | ||
| 114 | (defcustom eshell-cp-overwrite-files t | 132 | (defcustom eshell-cp-overwrite-files t |
| @@ -116,9 +134,12 @@ Otherwise, `rmdir' is required." | |||
| 116 | :type 'boolean | 134 | :type 'boolean |
| 117 | :group 'eshell-unix) | 135 | :group 'eshell-unix) |
| 118 | 136 | ||
| 119 | (defcustom eshell-ln-interactive-query (= (user-uid) 0) | 137 | (defcustom eshell-ln-interactive-query 'root |
| 120 | "If non-nil, `ln' will query before overwriting anything." | 138 | "When `ln' should query before overwriting anything. |
| 121 | :type 'boolean | 139 | If t, always query. If nil, never query. If `root', query when |
| 140 | the user is logged in as root (including when `default-directory' | ||
| 141 | is remote with a root user)." | ||
| 142 | :type 'eshell-interactive-query | ||
| 122 | :group 'eshell-unix) | 143 | :group 'eshell-unix) |
| 123 | 144 | ||
| 124 | (defcustom eshell-ln-overwrite-files nil | 145 | (defcustom eshell-ln-overwrite-files nil |
| @@ -159,6 +180,17 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | |||
| 159 | (defvar em-recursive) | 180 | (defvar em-recursive) |
| 160 | (defvar em-verbose) | 181 | (defvar em-verbose) |
| 161 | 182 | ||
| 183 | (defun eshell-interactive-query-p (value) | ||
| 184 | "Return non-nil if a command should query the user according to VALUE. | ||
| 185 | If VALUE is nil, return nil (never query). If `root', return | ||
| 186 | non-nil if the user is logged in as root (including when | ||
| 187 | `default-directory' is remote with a root user; see | ||
| 188 | `file-user-uid'). If VALUE is any other non-nil value, return | ||
| 189 | non-nil (always query)." | ||
| 190 | (if (eq value 'root) | ||
| 191 | (= (file-user-uid) 0) | ||
| 192 | value)) | ||
| 193 | |||
| 162 | (defun eshell/man (&rest args) | 194 | (defun eshell/man (&rest args) |
| 163 | "Invoke man, flattening the arguments appropriately." | 195 | "Invoke man, flattening the arguments appropriately." |
| 164 | (funcall 'man (apply 'eshell-flatten-and-stringify args))) | 196 | (funcall 'man (apply 'eshell-flatten-and-stringify args))) |
| @@ -249,7 +281,8 @@ argument." | |||
| 249 | :usage "[OPTION]... FILE... | 281 | :usage "[OPTION]... FILE... |
| 250 | Remove (unlink) the FILE(s).") | 282 | Remove (unlink) the FILE(s).") |
| 251 | (unless em-interactive | 283 | (unless em-interactive |
| 252 | (setq em-interactive eshell-rm-interactive-query)) | 284 | (setq em-interactive (eshell-interactive-query-p |
| 285 | eshell-rm-interactive-query))) | ||
| 253 | (if (and force-removal em-interactive) | 286 | (if (and force-removal em-interactive) |
| 254 | (setq em-interactive nil)) | 287 | (setq em-interactive nil)) |
| 255 | (while args | 288 | (while args |
| @@ -523,7 +556,8 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. | |||
| 523 | [OPTION] DIRECTORY...") | 556 | [OPTION] DIRECTORY...") |
| 524 | (let ((no-dereference t)) | 557 | (let ((no-dereference t)) |
| 525 | (eshell-mvcpln-template "mv" "moving" 'rename-file | 558 | (eshell-mvcpln-template "mv" "moving" 'rename-file |
| 526 | eshell-mv-interactive-query | 559 | (eshell-interactive-query-p |
| 560 | eshell-mv-interactive-query) | ||
| 527 | eshell-mv-overwrite-files)))) | 561 | eshell-mv-overwrite-files)))) |
| 528 | 562 | ||
| 529 | (put 'eshell/mv 'eshell-no-numeric-conversions t) | 563 | (put 'eshell/mv 'eshell-no-numeric-conversions t) |
| @@ -561,7 +595,8 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") | |||
| 561 | (if archive | 595 | (if archive |
| 562 | (setq preserve t no-dereference t em-recursive t)) | 596 | (setq preserve t no-dereference t em-recursive t)) |
| 563 | (eshell-mvcpln-template "cp" "copying" 'copy-file | 597 | (eshell-mvcpln-template "cp" "copying" 'copy-file |
| 564 | eshell-cp-interactive-query | 598 | (eshell-interactive-query-p |
| 599 | eshell-cp-interactive-query) | ||
| 565 | eshell-cp-overwrite-files preserve))) | 600 | eshell-cp-overwrite-files preserve))) |
| 566 | 601 | ||
| 567 | (put 'eshell/cp 'eshell-no-numeric-conversions t) | 602 | (put 'eshell/cp 'eshell-no-numeric-conversions t) |
| @@ -594,7 +629,8 @@ with `--symbolic'. When creating hard links, each TARGET must exist.") | |||
| 594 | (if symbolic | 629 | (if symbolic |
| 595 | 'make-symbolic-link | 630 | 'make-symbolic-link |
| 596 | 'add-name-to-file) | 631 | 'add-name-to-file) |
| 597 | eshell-ln-interactive-query | 632 | (eshell-interactive-query-p |
| 633 | eshell-ln-interactive-query) | ||
| 598 | eshell-ln-overwrite-files)))) | 634 | eshell-ln-overwrite-files)))) |
| 599 | 635 | ||
| 600 | (put 'eshell/ln 'eshell-no-numeric-conversions t) | 636 | (put 'eshell/ln 'eshell-no-numeric-conversions t) |
| @@ -960,7 +996,7 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 960 | 996 | ||
| 961 | (defun eshell/whoami (&rest _args) | 997 | (defun eshell/whoami (&rest _args) |
| 962 | "Make \"whoami\" Tramp aware." | 998 | "Make \"whoami\" Tramp aware." |
| 963 | (or (file-remote-p default-directory 'user) (user-login-name))) | 999 | (eshell-user-login-name)) |
| 964 | 1000 | ||
| 965 | (defvar eshell-diff-window-config nil) | 1001 | (defvar eshell-diff-window-config nil) |
| 966 | 1002 | ||
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index c0685757789..3608c78ba2b 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el | |||
| @@ -502,6 +502,11 @@ list." | |||
| 502 | (sit-for 0) | 502 | (sit-for 0) |
| 503 | (error nil))) | 503 | (error nil))) |
| 504 | 504 | ||
| 505 | (defun eshell-user-login-name () | ||
| 506 | "Return the connection-aware value of the user's login name. | ||
| 507 | See also `user-login-name'." | ||
| 508 | (or (file-remote-p default-directory 'user) (user-login-name))) | ||
| 509 | |||
| 505 | (defun eshell-read-passwd-file (file) | 510 | (defun eshell-read-passwd-file (file) |
| 506 | "Return an alist correlating gids to group names in FILE." | 511 | "Return an alist correlating gids to group names in FILE." |
| 507 | (let (names) | 512 | (let (names) |