Repositories / jai.git
tests/setup-setuid.sh.in
Clone (read-only): git clone http://git.guha-anderson.com/git/jai.git
#!/bin/sh
set -eu
abs_top_builddir='@TEST_ABS_TOP_BUILDDIR@'
link_path=$abs_top_builddir/jai.suid
usage() {
cat <<EOF
usage: $0 [--user USER]
Installs a setuid-root copy of jai for running the test suite without sudo.
The binary is placed in a private per-user directory under /var/tmp and
$link_path is updated to point to it.
After setup, just run:
make check
EOF
}
fail() {
printf 'FAIL: %s\n' "$*" >&2
exit 1
}
default_test_user() {
owner_uid=$(stat -c %u "$abs_top_builddir") || return 1
if [ "$owner_uid" -eq 0 ]; then
owner_uid=$(stat -c %u "$(dirname "$abs_top_builddir")") || return 1
fi
[ "$owner_uid" -ne 0 ] || return 1
owner_entry=$(getent passwd "$owner_uid") || return 1
printf '%s\n' "$owner_entry" | cut -d: -f1
}
test_user=
while [ $# -gt 0 ]; do
case $1 in
--user)
[ $# -ge 2 ] || {
usage >&2
exit 1
}
test_user=$2
shift 2
;;
--help)
usage
exit 0
;;
*)
usage >&2
exit 1
;;
esac
done
[ "$(id -u)" -eq 0 ] || fail 'setup-setuid.sh must be run as root'
if [ -z "$test_user" ]; then
if [ -n "${JAI_TEST_USER:-}" ]; then
test_user=$JAI_TEST_USER
elif [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
test_user=$SUDO_USER
elif test_user=$(default_test_user); then
:
else
fail 'specify --user when running as root without SUDO_USER or a non-root build directory owner'
fi
fi
jai_bin=$abs_top_builddir/jai
install_root=/var/tmp/jai-test-$test_user
install_path=$install_root/jai
[ -x "$jai_bin" ] || fail "$jai_bin has not been built"
test_user_uid=$(id -u "$test_user") || fail "cannot find uid for $test_user"
test_user_gid=$(id -g "$test_user") || fail "cannot find primary gid for $test_user"
prepare_install_root() {
if [ -e "$install_root" ]; then
[ -d "$install_root" ] || fail "$install_root exists but is not a directory"
[ ! -L "$install_root" ] || fail "$install_root must not be a symlink"
else
mkdir "$install_root"
fi
chown "$test_user_uid:$test_user_gid" "$install_root"
chmod 700 "$install_root"
[ -d "$install_root" ] || fail "$install_root is not a directory"
[ ! -L "$install_root" ] || fail "$install_root must not be a symlink"
owner_uid=$(stat -Lc %u "$install_root") || fail "cannot stat $install_root"
mode=$(stat -Lc %a "$install_root") || fail "cannot stat $install_root"
[ "$owner_uid" = "$test_user_uid" ] ||
fail "$install_root is not owned by $test_user"
[ "$mode" = "700" ] ||
fail "$install_root must have mode 0700"
}
installed_jai_is_current() {
[ -u "$install_path" ] || return 1
[ -r "$install_path" ] || return 1
[ -x "$install_path" ] || return 1
mode=$(stat -Lc %a "$install_path") || return 1
[ "$mode" = "4555" ] || return 1
[ -L "$link_path" ] || return 1
[ "$(readlink "$link_path")" = "$install_path" ] || return 1
cmp -s "$jai_bin" "$install_path" 2>/dev/null
}
update_link() {
rm -f "$link_path"
ln -s "$install_path" "$link_path"
}
prepare_install_root
if installed_jai_is_current; then
printf '%s is up to date\n' "$install_path"
exit 0
fi
install -o root -g root -m 4555 "$jai_bin" "$install_path"
update_link
printf 'Installed %s\n' "$install_path"
printf 'Linked %s -> %s\n' "$link_path" "$install_path"
printf 'Users can remove %s when they are done\n' "$install_path"
printf 'Run: make check\n'