libvirt/tools/libvirt_recover_xattrs.sh
Michal Privoznik e19171b40c tools: Fix dry run of libvirt_recover_xattrs.sh
The libvirt_recover_xattrs.sh script can be used to remove stale
XATTRs that were left behind by secdrivers (which should happen
only if there's an imbalance between set and restore calls).
Anyway, the script has '-n' switch which is supposed to perform
just a dry run, i.e. just to report which files have XATTRs set
without any attempt to remove them.

But, when rewriting the script a few months ago a typo was
introduced which made the script report no files even if there
were files with XATTRs.

Fixes: 5377177f80
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2021-03-02 09:42:38 +01:00

119 lines
2.4 KiB
Bash
Executable File

#!/bin/bash
function die {
echo $@ >&2
exit 1
}
function show_help {
cat << EOF
Usage: ${0##*/} -[hqnu] [PATH ...]
Clear out any XATTRs set by libvirt on all files that have them.
The idea is to reset refcounting, should it break.
-h display this help and exit
-q quiet (don't print which files are being fixed)
-n dry run; don't remove any XATTR just report the file name
-u unsafe; don't check whether there are running VMs; PATH must be specified
PATH can be specified to refine search to only to given path
instead of whole root ('/'), which is the default.
EOF
}
QUIET=0
DRY_RUN=0
UNSAFE=0
# So far only qemu and lxc drivers use security driver.
URI=("qemu:///system"
"lxc:///system")
if [ $(whoami) != "root" ]; then
die "Must be run as root"
fi
while getopts hqnu opt; do
case $opt in
h)
show_help
exit 0
;;
q)
QUIET=1
;;
n)
DRY_RUN=1
;;
u)
UNSAFE=1
;;
*)
show_help >&2
exit 1
;;
esac
done
case $(uname -s) in
Linux)
XATTR_PREFIX="trusted.libvirt.security"
;;
FreeBSD)
XATTR_PREFIX="system.libvirt.security"
;;
*)
die "$0 is not supported on this platform"
;;
esac
if [ ${DRY_RUN} -eq 0 ] && [ ${UNSAFE} -eq 0 ]; then
for u in ${URI[*]} ; do
if [ -n "`virsh -q -c $u list 2>/dev/null`" ]; then
die "There are still some domains running for $u"
fi
done
fi
declare -a XATTRS
for i in "dac" "selinux"; do
XATTRS+=("$XATTR_PREFIX.$i" "$XATTR_PREFIX.ref_$i" "$XATTR_PREFIX.timestamp_$i")
done
fix_xattrs() {
local DIR="$1"
for i in $(getfattr -R -d -m ${XATTR_PREFIX} --absolute-names ${DIR} 2>/dev/null | grep "^# file:" | cut -d':' -f 2); do
if [ ${DRY_RUN} -ne 0 ]; then
getfattr -d -m ${XATTR_PREFIX} --absolute-names $i
continue
fi
if [ ${QUIET} -eq 0 ]; then
echo "Fixing $i";
fi
for x in ${XATTRS[*]}; do
setfattr -x $x $i
done
done
}
shift $((OPTIND - 1))
if [ $# -gt 0 ]; then
while [ $# -gt 0 ]; do
fix_xattrs "$1"
shift $((OPTIND - 1))
done
else
if [ ${UNSAFE} -eq 1 ]; then
die "Unsafe mode (-u) requires explicit 'PATH' argument"
fi
fix_xattrs "/"
fi