From: Oliver Kiddle <okiddle@yahoo.co.uk>
To: Zsh workers <zsh-workers@zsh.org>
Subject: PATCH: completion of SELinux contexts
Date: Fri, 27 Sep 2019 00:10:15 +0200 [thread overview]
Message-ID: <78351-1569535815.914285@9und.9YLS.ptXQ> (raw)
There are quite a number of commands that have an option that takes an
SELinux context as it's argument. Typically we've not handled this in
completion functions. However it isn't too hard to do a reasonable job
of completing them (apart from the level component which I don't really
understand). The following adds helper functions for contexts, users,
roles and types and a completion function for chcon (which comes from
util-linux). And modifies completions for cp, find, install, mkdir,
mknod and sudo to use the new helpers.
Oliver
diff --git a/Completion/Linux/Command/_chcon b/Completion/Linux/Command/_chcon
new file mode 100644
index 000000000..2d523f287
--- /dev/null
+++ b/Completion/Linux/Command/_chcon
@@ -0,0 +1,24 @@
+#compdef chcon
+
+local ign
+
+(( $#words > 2 )) && ign='!'
+_arguments -C -s -S \
+ '(-h --no-dereference)--dereference[dereference symlinks]' \
+ '(-h --no-dereference --dereference)'{-h,--no-dereference}'[operate on symlinks themselves]' \
+ '(1 -u --user -r --role -l --range -t --type)--reference=[copy security context of specified file]:file:_files' \
+ '(1 --reference -u --user)'{-u+,--user=}'[set user in the target security context]: :_selinux_users' \
+ '(1 --reference -r --role)'{-r+,--role=}'[set role in the target security context]: :_selinux_roles' \
+ '(1 --reference -t --type)'{-t+,--type=}'[set type in the target security context]: :_selinux_types' \
+ '(1 --reference -l --range)'{-l+,--range=}'[set range in the target security context]:selinux range' \
+ '(--recursive -R)'{--recursive,-R}'[recurse subdirectories]' \
+ '(-v --verbose)'{-v,--verbose}'[output a diagnostic for every file processed]' \
+ '(-H -L -P)-H[follow symlinks on the command line]' \
+ '(-H -L -P)-L[follow all symlinks]' \
+ "(-H -L -P)-P[don't follow symlinks (default)]" \
+ '!(--preserve-root)--no-preserve-root' \
+ "--preserve-root[fail to operate recursively on '/']" \
+ '(--reference -u --user -r --role -l --range -t --type)1:security context:_selinux_contexts' \
+ "${ign}--help[display help information]" \
+ "${ign}--version[display version information]" \
+ '*:file:_files'
diff --git a/Completion/Linux/Type/_selinux_contexts b/Completion/Linux/Type/_selinux_contexts
new file mode 100644
index 000000000..4c2cf4288
--- /dev/null
+++ b/Completion/Linux/Type/_selinux_contexts
@@ -0,0 +1,14 @@
+#autoload
+
+local -a parts suf
+
+parts=( users roles types )
+while compset -P 1 '*:' && (( $+parts[1] )) ; do
+ shift parts
+done
+if (( $+parts[1] )); then
+ compset -S ':*' || suf=( -S : )
+ _selinux_$parts[1] $suf
+else
+ _message -e selinux-ranges 'selinux range'
+fi
diff --git a/Completion/Linux/Type/_selinux_roles b/Completion/Linux/Type/_selinux_roles
new file mode 100644
index 000000000..92b4c36cb
--- /dev/null
+++ b/Completion/Linux/Type/_selinux_roles
@@ -0,0 +1,7 @@
+#autoload
+
+local -a seroles expl
+
+seroles=( ${(f)"$(_call_program selinux-roles seinfo --flat -r)"} )
+_description selinux-roles expl "selinux role"
+compadd "$@" "$expl[@]" -a seroles
diff --git a/Completion/Linux/Type/_selinux_types b/Completion/Linux/Type/_selinux_types
new file mode 100644
index 000000000..ef31f45d2
--- /dev/null
+++ b/Completion/Linux/Type/_selinux_types
@@ -0,0 +1,7 @@
+#autoload
+
+local -a setypes expl
+
+setypes=( ${(f)"$(_call_program selinux-types seinfo --flat -t)"} )
+_description selinux-types expl "selinux type"
+compadd "$@" "$expl[@]" -a setypes
diff --git a/Completion/Linux/Type/_selinux_users b/Completion/Linux/Type/_selinux_users
new file mode 100644
index 000000000..f046c92cf
--- /dev/null
+++ b/Completion/Linux/Type/_selinux_users
@@ -0,0 +1,8 @@
+#autoload
+
+local -a seusers expl
+
+seusers=( ${(f)"$(_call_program selinux-users seinfo --flat -u)"} )
+(( $#seusers )) || seusers=( guest_u root staff_u sysadm_u system_u unconfined_u user_u )
+_description selinux-users expl "selinux user"
+compadd "$@" "$expl[@]" -a seusers
diff --git a/Completion/Unix/Command/_cp b/Completion/Unix/Command/_cp
index ae448213a..f7411055b 100644
--- a/Completion/Unix/Command/_cp
+++ b/Completion/Unix/Command/_cp
@@ -32,7 +32,7 @@ if _pick_variant gnu=GNU unix --version; then
'(-v --verbose)'{-v,--verbose}'[explain what is being done]' \
'(-x --one-file-system)'{-x,--one-file-system}'[stay on this file system]' \
'(--context)-Z[set destination SELinux security context]' \
- '(-Z)--context=-[set destination SELinux security context]::context' \
+ '(-Z)--context=-[set destination SELinux security context]:: :_selinux_contexts' \
'(- *)--help' '(- *)--version' \
'*:file or directory:_files'
else
diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find
index 3b9150b17..916fcf2e6 100644
--- a/Completion/Unix/Command/_find
+++ b/Completion/Unix/Command/_find
@@ -98,7 +98,7 @@ case $variant in
args+=(
'(- *)-help' '(-)--help'
'(- *)-version' '(-)--version'
- '-D[print diagnostics]:debug option:(help tree search stat rates opt exec)'
+ '-D[print diagnostics]:debug option:(exec opt rates search stat time tree all help)'
'-O+[enable query optimisation]:level:(1 2 3)'
'*-daystart'
'-regextype:regexp syntax:(help findutils-default awk egrep ed emacs gnu-awk grep posix-awk posix-basic posix-egrep posix-extended posix-minimal-basic sed)'
@@ -116,7 +116,7 @@ case $variant in
'*-fprintf:output file:_files:output format'
'*-printf:output format'
)
- [[ $OSTYPE = linux-gnu ]] && args+=( '*-context:SELinux context' )
+ [[ $OSTYPE = linux-gnu ]] && args+=( '*-context:SELinux context (glob pattern):_selinux_contexts' )
;;
esac
diff --git a/Completion/Unix/Command/_install b/Completion/Unix/Command/_install
index 60b0f6153..5ad84645e 100644
--- a/Completion/Unix/Command/_install
+++ b/Completion/Unix/Command/_install
@@ -25,7 +25,7 @@ if _pick_variant gnu='Free Soft' unix --version; then
args+=(
$common_args
'(-b --backup)--backup=[create backup; optionally specify method]:: :->controls'
- "${lx}--context=[like -Z, or specify SELinux security context to set]::SELinux security context"
+ "${lx}--context=-[like -Z, or specify SELinux security context to set]::SELinux security context:_selinux_contexts"
'-D[create all leading destination path components]'
'(: -)--help[display help information]'
"${lx}--preserve-context[preserve SELinux security context]"
diff --git a/Completion/Unix/Command/_mkdir b/Completion/Unix/Command/_mkdir
index 0ae6be14b..4cd6bda32 100644
--- a/Completion/Unix/Command/_mkdir
+++ b/Completion/Unix/Command/_mkdir
@@ -22,7 +22,8 @@ case $variant in
aopts=()
if [[ $OSTYPE == linux* ]]; then
args+=(
- '(-Z --context)'{-Z,--context=}'[set SELinux context]:SELinux context'
+ '(--context)-Z[set SELinux context]'
+ '(-Z)--context=-[set SELinux context]::SELinux context:_selinux_contexts'
)
fi
args+=(
diff --git a/Completion/Unix/Command/_mkfifo b/Completion/Unix/Command/_mkfifo
index 4f1d8c87e..a055e4a1c 100644
--- a/Completion/Unix/Command/_mkfifo
+++ b/Completion/Unix/Command/_mkfifo
@@ -10,7 +10,7 @@ if _pick_variant gnu='Free Soft' unix --version; then
)
[[ $OSTYPE == linux* ]] && args+=(
'(--context)-Z[set SELinux security context to default]'
- '(-Z)--context=-[like -Z, or specify SELinux security context]:SELinux security context'
+ '(-Z)--context=-[like -Z, or specify SELinux security context]::SELinux security context:_selinux_contexts'
)
else
aopts=( -A '-*' )
diff --git a/Completion/Unix/Command/_mknod b/Completion/Unix/Command/_mknod
index 902f49b9f..8f07328db 100644
--- a/Completion/Unix/Command/_mknod
+++ b/Completion/Unix/Command/_mknod
@@ -22,7 +22,7 @@ if _pick_variant gnu='Free Soft' $OSTYPE --version; then
)
[[ $OSTYPE == linux* ]] && args+=(
'(--context)-Z[set SELinux security context to default]'
- '(-Z)--context=-[like -Z, or specify SELinux security context]:SELinux security context'
+ '(-Z)--context=-[like -Z, or specify SELinux security context]::SELinux security context:_selinux_contexts'
)
else
aopts=( -A '-*' )
diff --git a/Completion/Unix/Command/_sudo b/Completion/Unix/Command/_sudo
index 10fa2e82e..41e32cbae 100644
--- a/Completion/Unix/Command/_sudo
+++ b/Completion/Unix/Command/_sudo
@@ -23,9 +23,9 @@ args=(
\*{-l,--list}"[list user's privileges or check a specific command]"
'(-n --non-interactive)'{-n,--non-interactive}'[non-interactive mode, no prompts are used]'
'(-p --prompt)'{-p+,--prompt=}'[use the specified password prompt]:prompt'
- '(-r --role)'{-r+,--role=}'[create SELinux security context with specified role]:role'
+ '(-r --role)'{-r+,--role=}'[create SELinux security context with specified role]: :_selinux_roles'
'(-S --stdin)'{-S,--stdin}'[read password from standard input]'
- '(-t --type)'{-t+,--type=}'[create SELinux security context with specified type]:type'
+ '(-t --type)'{-t+,--type=}'[create SELinux security context with specified type]: :_selinux_types'
'(-T --command-timeout)'{-T+,--command-timeout=}'[terminate command after specified time limit]:timeout'
'(-U --other-user)'{-U+,--other-user=}'[in list mode, display privileges for user]:user:_users'
'(-u --user)'{-u+,--user=}'[run command (or edit file) as specified user]:user:_users'
reply other threads:[~2019-09-26 22:21 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=78351-1569535815.914285@9und.9YLS.ptXQ \
--to=okiddle@yahoo.co.uk \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).