about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2016-09-11 13:22:35 +0200
committerOliver Kiddle <opk@zsh.org>2016-09-11 13:49:22 +0200
commit8011fe8a582bd3c018a98e0e2c08f65233bcf0fc (patch)
treece6612c1e1bc5e6618b86e8d0b7b7743714b09c9
parentf368720b8b9b481f82cef2e84a7e035864dff5f1 (diff)
downloadzsh-8011fe8a582bd3c018a98e0e2c08f65233bcf0fc.tar.gz
zsh-8011fe8a582bd3c018a98e0e2c08f65233bcf0fc.tar.xz
zsh-8011fe8a582bd3c018a98e0e2c08f65233bcf0fc.zip
39261 (tweaked cf. Daniel: 39275): don't unconditionally elevate privileges with sudo in completion functions
A new gain-privileges style enables it and a _comp_priv_prefix array
added for tracking how to match privileges for the current command
-rw-r--r--ChangeLog15
-rw-r--r--Completion/BSD/Command/_jexec1
-rw-r--r--Completion/Base/Core/_main_complete1
-rw-r--r--Completion/Base/Utility/_call_program11
-rw-r--r--Completion/Debian/Command/_dchroot1
-rw-r--r--Completion/Debian/Command/_dchroot-dsa1
-rw-r--r--Completion/Debian/Command/_schroot1
-rw-r--r--Completion/Mandriva/Command/_rebootin2
-rw-r--r--Completion/Solaris/Command/_pfexec2
-rw-r--r--Completion/Solaris/Command/_zlogin2
-rw-r--r--Completion/Unix/Command/_dsh1
-rw-r--r--Completion/Unix/Command/_fsh1
-rw-r--r--Completion/Unix/Command/_libvirt10
-rw-r--r--Completion/Unix/Command/_mosh1
-rw-r--r--Completion/Unix/Command/_rlogin1
-rw-r--r--Completion/Unix/Command/_ssh1
-rw-r--r--Completion/Unix/Command/_sudo2
-rw-r--r--Doc/Zsh/compsys.yo59
18 files changed, 95 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 7fba3550c..78931adbb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2016-09-11  Oliver Kiddle  <opk@zsh.org>
+
+	* 39261 (tweaked cf. Daniel: 39275): Doc/Zsh/compsys.yo:
+	Completion/Base/Core/_main_complete,
+	Completion/Base/Utility/_call_program,
+	Completion/Debian/Command/_dchroot,
+	Completion/Debian/Command/_dchroot-dsa,
+	Completion/Debian/Command/_schroot,
+	Completion/Solaris/Command/_pfexec,
+	Completion/Solaris/Command/_zlogin, Completion/Unix/Command/_dsh,
+	Completion/Unix/Command/_fsh, Completion/Unix/Command/_libvirt,
+	Completion/Unix/Command/_mosh, Completion/Unix/Command/_rlogin,
+	Completion/Unix/Command/_ssh, Completion/Unix/Command/_sudo:
+	don't unconditionally gain privileges with sudo for completion
+
 2016-09-11  Daniel Shahaf  <d.s@daniel.shahaf.name>
 
 	* 39252: Src/Zle/compcore.c, Src/Zle/compctl.c,
diff --git a/Completion/BSD/Command/_jexec b/Completion/BSD/Command/_jexec
index 279812bbc..85829d10e 100644
--- a/Completion/BSD/Command/_jexec
+++ b/Completion/BSD/Command/_jexec
@@ -2,6 +2,7 @@
 
 _jexec_normal() {
   local PATH=$PATH
+  local -a _comp_priv_prefix
   # relative paths are relative to the jail's root
   path=( "$(command jls -j $words[1] path)"/$^path )
   shift 1 words; (( CURRENT-- ))
diff --git a/Completion/Base/Core/_main_complete b/Completion/Base/Core/_main_complete
index 9c4cfac85..c292ce7d7 100644
--- a/Completion/Base/Core/_main_complete
+++ b/Completion/Base/Core/_main_complete
@@ -38,6 +38,7 @@ local func funcs ret=1 tmp _compskip format nm call match min max i num\
       _saved_colors="$ZLS_COLORS" \
       _saved_colors_set=${+ZLS_COLORS} \
       _ambiguous_color=''
+local -a _comp_priv_prefix
 
 # _precommand sets this to indicate we are following a precommand modifier
 local -a precommands
diff --git a/Completion/Base/Utility/_call_program b/Completion/Base/Utility/_call_program
index 010e09476..95c761e65 100644
--- a/Completion/Base/Utility/_call_program
+++ b/Completion/Base/Utility/_call_program
@@ -1,6 +1,13 @@
 #autoload +X
 
 local tmp err_fd=-1
+local -a prefix
+
+if [[ "$1" = -p ]]; then
+  shift
+  zstyle -t ":completion:${curcontext}:${1}" gain-privileges &&
+      prefix=( $_comp_priv_prefix )
+fi
 
 if (( ${debug_fd:--1} > 2 )) || [[ ! -t 2 ]]
 then exec {err_fd}>&2	# debug_fd is saved stderr, 2 is trace or redirect
@@ -13,10 +20,10 @@ if zstyle -s ":completion:${curcontext}:${1}" command tmp; then
   if [[ "$tmp" = -* ]]; then
     eval "$tmp[2,-1]" "$argv[2,-1]"
   else
-    eval "$tmp"
+    eval $prefix "$tmp"
   fi
 else
-  eval "$argv[2,-1]"
+  eval $prefix "$argv[2,-1]"
 fi 2>&$err_fd
 
 } always {
diff --git a/Completion/Debian/Command/_dchroot b/Completion/Debian/Command/_dchroot
index c26e5691a..2a6f5d808 100644
--- a/Completion/Debian/Command/_dchroot
+++ b/Completion/Debian/Command/_dchroot
@@ -2,6 +2,7 @@
 
 local expl context state line
 typeset -A opt_args
+local -a _comp_priv_prefix
 
 _arguments -S \
        '(-h --help)'{-h,--help}'[help]' \
diff --git a/Completion/Debian/Command/_dchroot-dsa b/Completion/Debian/Command/_dchroot-dsa
index d4668b553..e8e981b84 100644
--- a/Completion/Debian/Command/_dchroot-dsa
+++ b/Completion/Debian/Command/_dchroot-dsa
@@ -2,6 +2,7 @@
 
 local expl context state line
 typeset -A opt_args
+local -a _comp_priv_prefix
 
 _arguments -S \
        '(-h --help)'{-h,--help}'[help]' \
diff --git a/Completion/Debian/Command/_schroot b/Completion/Debian/Command/_schroot
index 06117be88..117df45ef 100644
--- a/Completion/Debian/Command/_schroot
+++ b/Completion/Debian/Command/_schroot
@@ -2,6 +2,7 @@
 
 local expl context state line
 typeset -A opt_args
+local -a _comp_priv_prefix
 
 _arguments -S \
        '(-h --help)'{-h,--help}'[help]' \
diff --git a/Completion/Mandriva/Command/_rebootin b/Completion/Mandriva/Command/_rebootin
index 3f30b2591..284ff08f1 100644
--- a/Completion/Mandriva/Command/_rebootin
+++ b/Completion/Mandriva/Command/_rebootin
@@ -2,7 +2,7 @@
 
 local context state line expl
 typeset -A opt_args
-local loader=$(sudo detectloader -q)
+local loader=${$(_call_program -p entries detectloader -q):-GRUB}
 
 _arguments -s \
     '-n[no immediate reboot just set the flags for next reboot]' \
diff --git a/Completion/Solaris/Command/_pfexec b/Completion/Solaris/Command/_pfexec
index 227336223..3f1f3e733 100644
--- a/Completion/Solaris/Command/_pfexec
+++ b/Completion/Solaris/Command/_pfexec
@@ -25,7 +25,7 @@ _pfexec() {
  	_arguments \
 		'-P[privileges to acquire]:privspec:_privset' \
  		'(-):command name: _command_names -e' \
- 		'*::arguments: _normal'
+		'*::arguments:{ _comp_priv_prefix=( $words[1] ${(kv)opt_args[-P]} ) ; _normal }'
 }
 
 _pfexec "$@"
diff --git a/Completion/Solaris/Command/_zlogin b/Completion/Solaris/Command/_zlogin
index 04018eb87..065f55b03 100644
--- a/Completion/Solaris/Command/_zlogin
+++ b/Completion/Solaris/Command/_zlogin
@@ -1,6 +1,8 @@
 #compdef zlogin
 # Synced with the Nevada build 162 man page
 
+local -a _comp_priv_prefix
+
 _zlogin() {
 	_arguments -s \
 		'-E[Disable escape character]' \
diff --git a/Completion/Unix/Command/_dsh b/Completion/Unix/Command/_dsh
index 688e024ce..8c5c23208 100644
--- a/Completion/Unix/Command/_dsh
+++ b/Completion/Unix/Command/_dsh
@@ -2,6 +2,7 @@
 
 local curcontext="$curcontext" state line expl
 typeset -A opt_args
+local -a _comp_priv_prefix
 
 _arguments -s -C -S \
   '(-v --verbose -q --quiet)'{-v,--verbose}'[verbose output]' \
diff --git a/Completion/Unix/Command/_fsh b/Completion/Unix/Command/_fsh
index d9ced5feb..c39373117 100644
--- a/Completion/Unix/Command/_fsh
+++ b/Completion/Unix/Command/_fsh
@@ -1,6 +1,7 @@
 #compdef fsh
 
 local curcontext="$curcontext" state line ret=1
+local -a _comp_priv_prefix
 
 _arguments -C \
   '(- : *)'{-h,--help}'[display help information]' \
diff --git a/Completion/Unix/Command/_libvirt b/Completion/Unix/Command/_libvirt
index 658e197dc..17b02be81 100644
--- a/Completion/Unix/Command/_libvirt
+++ b/Completion/Unix/Command/_libvirt
@@ -155,7 +155,7 @@ case $state in
         return 1
       ;;
       --device)
-        values; values=( $(_call_program nodedevs "virsh $conn_opt nodedev-list") )
+        values; values=( $(_call_program devices "virsh $conn_opt nodedev-list") )
         [[ -n $values ]] && _wanted devices expl device compadd ${=values} && return 0
         return 1
       ;;
@@ -204,7 +204,7 @@ case $state in
       fi
     fi
     [[ -z $_cache_virsh_cmd_opts[$cmd] ]] && \
-      _cache_virsh_cmd_opts[$cmd]=${(M)${${${${=${(f)"$(_call_program virsh virsh help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
+      _cache_virsh_cmd_opts[$cmd]=${(M)${${${${=${(f)"$(_call_program options virsh help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
     [[ -n ${=_cache_virsh_cmd_opts[$cmd]} ]] && \
       _values -w option ${(u)=_cache_virsh_cmd_opts[$cmd]} && ret=0
   ;;
@@ -218,16 +218,16 @@ case $state in
     done
     [[ -z $cmd ]] && return 1
     if [[ $words[CURRENT-1] == --server ]]; then
-      _wanted servers expl server compadd ${=${(S)${${(f)$(sudo virt-admin ${(Q)conn_opt} srv-list)}##*--- }//[0-9]* }} && return 0
+      _wanted servers expl server compadd ${=${(S)${${(f)$(_call_program -p servers virt-admin ${(Q)conn_opt} srv-list)}##*--- }//[0-9]* }} && return 0
     fi
     if [[ $words[CURRENT-1] == --client ]]; then
       local srv ; (( ${(k)words[(I)--server]} > 0 )) && srv=${words[1+${(k)words[(I)--server]}]}
       [[ -z $srv ]] && return 1
       [[ -n ${srv//[[:alnum:]]} ]] && return 1
-      _wanted clients expl client compadd ${=${${(f):-"$(sudo virt-admin ${(Q)conn_opt} srv-clients-list --server $srv 2>/dev/null)"}/ [a-z]*}//[^0-9]} && return 0
+      _wanted clients expl client compadd ${=${${(f):-"$(_call_program -p clients virt-admin ${(Q)conn_opt} srv-clients-list --server $srv 2>/dev/null)"}/ [a-z]*}//[^0-9]} && return 0
     fi
     [[ -z $_cache_virt_admin_cmd_opts[$cmd] ]] && \
-      _cache_virt_admin_cmd_opts[$cmd]=${(M)${${${${=${(f)"$(_call_program virt-admin virt-admin help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
+      _cache_virt_admin_cmd_opts[$cmd]=${(M)${${${${=${(f)"$(_call_program options virt-admin help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
     [[ -n $_cache_virt_admin_cmd_opts[$cmd] ]] && \
       _values -w option ${(u)=_cache_virt_admin_cmd_opts[$cmd]} && ret=0
   ;;
diff --git a/Completion/Unix/Command/_mosh b/Completion/Unix/Command/_mosh
index c19f6ebde..431fdbf9e 100644
--- a/Completion/Unix/Command/_mosh
+++ b/Completion/Unix/Command/_mosh
@@ -1,6 +1,7 @@
 #compdef mosh
 
 local curcontext="$curcontext" state line
+local -a _comp_priv_prefix
 
 _arguments -C \
   '(-)--help[display help information]' \
diff --git a/Completion/Unix/Command/_rlogin b/Completion/Unix/Command/_rlogin
index a04c6d068..8f74939fd 100644
--- a/Completion/Unix/Command/_rlogin
+++ b/Completion/Unix/Command/_rlogin
@@ -12,6 +12,7 @@ _rlogin () {
   rsh|remsh)
     local context state line ret=1
     typeset -A opt_args
+    local -a _comp_priv_prefix
 
     _arguments -s \
       '-n[ignore stdin]' \
diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh
index 7b2cdd8e1..5ee4fd2ad 100644
--- a/Completion/Unix/Command/_ssh
+++ b/Completion/Unix/Command/_ssh
@@ -605,6 +605,7 @@ _ssh () {
           hmac-sha2-256-96 hmac-sha2-512 hmac-sha2-512-96 && ret=0
       ;;
     command)
+      local -a _comp_priv_prefix
       shift 1 words
       (( CURRENT-- ))
       _normal
diff --git a/Completion/Unix/Command/_sudo b/Completion/Unix/Command/_sudo
index 63ac37f62..21b1ef4c6 100644
--- a/Completion/Unix/Command/_sudo
+++ b/Completion/Unix/Command/_sudo
@@ -48,7 +48,7 @@ else
     '(-H --set-home -i --login -s --shell -e --edit)'{-H,--set-home}"[set HOME variable to target user's home dir]" \
     '(-P --preserve-groups -i -login -s --shell -e --edit)'{-P,--preserve-groups}"[preserve group vector instead of setting to target's]" \
     '(-)1:command: _command_names -e'
-    '*::arguments: _normal'
+    '*::arguments:{ _comp_priv_prefix=( $words[1] -n ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]} ) ; _normal }'
   )
 fi
 
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index ecf17e728..bc036ada5 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -1842,6 +1842,15 @@ In the case of the tt(_match) completer, the style may also be set to
 the string `tt(pattern)'.  Then the pattern on the line is left
 unchanged if it does not match unambiguously.
 )
+kindex(gain-privileges, completion style)
+item(tt(gain-privileges))(
+If set to tt(true), this style enables the use of commands like tt(sudo)
+or tt(doas) to gain extra privileges when retrieving information for
+completion. This is only done when a command such as tt(sudo) appears on
+the command-line. To force the use of, e.g. tt(sudo) or to override any
+prefix that might be added due to tt(gain-privileges), the tt(command)
+style can be used with a value that begins with a hyphen.
+)
 kindex(keep-prefix, completion style)
 item(tt(keep-prefix))(
 This style is used by the tt(_expand) completer.  If it is `true', the
@@ -3471,12 +3480,6 @@ generating matches all follow the convention of returning status zero if they
 generated completions and non-zero if no matching completions could be 
 added.
 
-Two more features are offered by the tt(_main_complete) function.  The
-arrays tt(compprefuncs) and tt(comppostfuncs) may contain
-names of functions that are to be called immediately before or after
-completion has been tried.  A function will only be called once unless
-it explicitly reinserts itself into the array.
-
 startitem()
 findex(_absolute_command_paths)
 item(tt(_absolute_command_paths))(
@@ -4173,7 +4176,7 @@ The return status of tt(_call_function) itself is zero if the function
 var(name) exists and was called and non-zero otherwise.
 )
 findex(_call_program)
-item(tt(_call_program) var(tag) var(string) ...)(
+item(tt(_call_program) [ tt(-p) ] var(tag) var(string) ...)(
 This function provides a mechanism for the user to override the use of an
 external command.  It looks up the tt(command) style with the supplied
 var(tag).  If the style is set, its value is used as the command to
@@ -4181,6 +4184,13 @@ execute.  The var(string)s from the call to tt(_call_program), or from the
 style if set, are concatenated with spaces between them and the resulting
 string is evaluated.  The return status is the return status of the command
 called.
+
+If the option `tt(-p)' is supplied it indicates that the command
+output is influenced by the permissions it is run with. If the
+tt(gain-privileges) style is set to true, tt(_call_program) will make
+use of commands such as tt(sudo), if present on the command-line, to
+match the permissions to whatever the final command is likely to run
+under.
 )
 findex(_combination)
 item(tt(_combination) [ tt(-s) var(pattern) ] var(tag) var(style) var(spec) ... var(field) var(opts) ...)(
@@ -5073,7 +5083,40 @@ ifnzman(noderef(The zsh/zleparameter Module)).
 )
 enditem()
 
-texinode(Completion Directories)()(Completion Functions)(Completion System)
+texinode(Completion System Variables)(Completion Directories)(Completion Functions)(Completion System)
+sect(Completion System Variables)
+cindex(completion system, variables)
+
+There are some standard variables, initialised by the tt(_main_complete)
+function and then used from other functions.
+
+The standard variables are:
+
+startitem()
+item(tt(_comp_caller_options))(
+The completion system uses tt(setopt) to set a number of options. This
+allows functions to be written without concern for compatibility with
+every possible combination of user options. However, sometimes completion
+needs to know what the user's option preferences are. These are saved
+in the tt(_comp_caller_options) associative array. Option names, spelled
+in lowercase without underscores, are mapped to one or other of the
+strings `tt(on)' and `tt(off)'.
+)
+
+item(tt(_comp_priv_prefix))(
+Completion functions such as tt(_sudo) can set the tt(_comp_priv_prefix)
+array to a command prefix that may then be used by tt(_call_program) to
+match the privileges when calling programs to generate matches.
+)
+enditem()
+
+Two more features are offered by the tt(_main_complete) function.  The
+arrays tt(compprefuncs) and tt(comppostfuncs) may contain
+names of functions that are to be called immediately before or after
+completion has been tried.  A function will only be called once unless
+it explicitly reinserts itself into the array.
+
+texinode(Completion Directories)()(Completion System Variables)(Completion System)
 sect(Completion Directories)
 cindex(completion system, directory structure)