diff --git a/.gitignore b/.gitignore index e5ba2ae30..a51b27425 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,7 @@ logsrvd/sudo_sendlog logsrvd/fuzz_[a-z]* plugins/sudoers/cvtsudoers +plugins/sudoers/harness plugins/sudoers/sudoers plugins/sudoers/sudoreplay plugins/sudoers/testsudoers diff --git a/.hgignore b/.hgignore index c0e733ef0..44db85ee5 100644 --- a/.hgignore +++ b/.hgignore @@ -65,7 +65,7 @@ Makefile$ ^logsrvd/sudo_(logsrvd|sendlog)$ ^logsrvd/fuzz_logsrvd_conf$ -^plugins/sudoers/(cvtsudoers|sudoers|sudoreplay|testsudoers|tsdump|visudo|prologue|check_[a-z0-9_]+)$ +^plugins/sudoers/(cvtsudoers|harness|sudoers|sudoreplay|testsudoers|tsdump|visudo|prologue|check_[a-z0-9_]+)$ ^plugins/sudoers/fuzz_(policy|sudoers(_ldif)?)$ ^plugins/sudoers/.*\.(out|toke|err|json|ldif|sudo|ldif2sudo)$ ^plugins/sudoers/regress/iolog_plugin/iolog$ diff --git a/MANIFEST b/MANIFEST index 1f1c968da..e9f765885 100644 --- a/MANIFEST +++ b/MANIFEST @@ -602,6 +602,7 @@ plugins/sudoers/gram.c plugins/sudoers/gram.h plugins/sudoers/gram.y plugins/sudoers/group_plugin.c +plugins/sudoers/harness.in plugins/sudoers/hexchar.c plugins/sudoers/ins_2001.h plugins/sudoers/ins_classic.h diff --git a/configure b/configure index 975dfdd9d..ddbe08ce9 100755 --- a/configure +++ b/configure @@ -32257,7 +32257,7 @@ elif test X"$TMPFILES_D" != X""; then fi -ac_config_files="$ac_config_files Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers" +ac_config_files="$ac_config_files Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/harness plugins/sudoers/sudoers" cat >confcache <<\_ACEOF @@ -33273,6 +33273,7 @@ do "plugins/sample_approval/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sample_approval/Makefile" ;; "plugins/system_group/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/system_group/Makefile" ;; "plugins/sudoers/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/Makefile" ;; + "plugins/sudoers/harness") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/harness" ;; "plugins/sudoers/sudoers") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/sudoers" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; diff --git a/configure.ac b/configure.ac index c2adf23ae..02c6c2fc7 100644 --- a/configure.ac +++ b/configure.ac @@ -5114,7 +5114,7 @@ elif test X"$TMPFILES_D" != X""; then AC_CONFIG_FILES([etc/init.d/sudo.conf]) fi -AC_CONFIG_FILES([Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers]) +AC_CONFIG_FILES([Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/harness plugins/sudoers/sudoers]) AC_OUTPUT diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in index a61ba3c3f..7b24e4265 100644 --- a/plugins/sudoers/Makefile.in +++ b/plugins/sudoers/Makefile.in @@ -673,130 +673,10 @@ check: $(TEST_PROGS) visudo testsudoers cvtsudoers check-fuzzer if test -f check_symbols; then \ ./check_symbols .libs/sudoers.so $(shlib_exp) || rval=`expr $$rval + $$?`; \ fi; \ - passed=0; failed=0; total=0; \ - mkdir -p regress/sudoers; \ - dir=sudoers; \ - for t in $(srcdir)/regress/$$dir/*.in; do \ - base=`basename $$t .in`; \ - out="regress/sudoers/$${base}.out"; \ - toke="regress/sudoers/$${base}.toke"; \ - json="regress/sudoers/$${base}.json"; \ - ldif="regress/sudoers/$${base}.ldif"; \ - sudo="regress/sudoers/$${base}.sudo"; \ - ldif2sudo="regress/sudoers/$${base}.ldif2sudo"; \ - ./testsudoers -dt <$$t >$$out 2>$$toke || true; \ - if cmp $$out $(srcdir)/$$out.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (parse): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (parse): FAIL"; \ - diff $$out $(srcdir)/$$out.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - if cmp $$toke $(srcdir)/$$toke.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (toke): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (toke): FAIL"; \ - diff $$toke $(srcdir)/$$toke.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - ./cvtsudoers -c "" -f json $$t >$$json 2>/dev/null || true; \ - total=`expr $$total + 1`; \ - if cmp $$json $(srcdir)/$$json.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (json): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (json): FAIL"; \ - diff $$json $(srcdir)/$$json.ok || true; \ - fi; \ - SUDOERS_BASE="ou=SUDOers,dc=sudo,dc=ws" \ - ./cvtsudoers -c "" -f ldif < $$t >$$ldif 2>/dev/null || true; \ - total=`expr $$total + 1`; \ - if cmp $$ldif $(srcdir)/$$ldif.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (ldif): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: (ldif) FAIL"; \ - diff $$ldif $(srcdir)/$$ldif.ok || true; \ - fi; \ - ./cvtsudoers -c "" -f sudoers $$t >$$sudo 2>/dev/null || true; \ - total=`expr $$total + 1`; \ - if ./visudo -qcf $$sudo; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (reparse): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: (reparse) FAIL"; \ - ./visudo -cf $$sudo || true; \ - fi; \ - if test -s $(srcdir)/$$ldif.ok; then \ - ./cvtsudoers -c "" -i ldif -f sudoers $(srcdir)/$$ldif.ok >$$ldif2sudo || true; \ - total=`expr $$total + 1`; \ - if cmp $$ldif2sudo $(srcdir)/$$ldif2sudo.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (ldif2sudo): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: (ldif2sudo) FAIL"; \ - diff $$ldif $(srcdir)/$$ldif.ok || true; \ - fi; \ - fi; \ - done; \ - echo "$$dir: $$passed/$$total tests passed; $$failed/$$total tests failed"; \ - if test $$failed -ne 0; then \ - rval=`expr $$rval + $$failed`; \ - fi; \ - for dir in testsudoers visudo cvtsudoers; do \ - mkdir -p regress/$$dir; \ - passed=0; failed=0; total=0; \ - for t in $(srcdir)/regress/$$dir/*.sh; do \ - base=`basename $$t .sh`; \ - out="regress/$$dir/$${base}.out"; \ - err="regress/$$dir/$${base}.err"; \ - status=0; \ - TESTSUDOERS=./testsudoers VISUDO=./visudo \ - CVTSUDOERS=./cvtsudoers TESTDIR=$(srcdir)/regress/$$dir \ - $(SHELL) $$t >$$out 2>$$err || status=$$?; \ - if cmp $$out $(srcdir)/$$out.ok >/dev/null; then \ - if test $$status -ne 0; then \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (exit $$status): FAIL"; \ - else \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base: OK"; \ - fi; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: FAIL"; \ - diff $$out $(srcdir)/$$out.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - if test -s $(srcdir)/$$err.ok; then \ - if cmp $$err $(srcdir)/$$err.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (stderr): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (stderr): FAIL"; \ - diff $$err $(srcdir)/$$err.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - elif test -s $$err; then \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (stderr): FAIL"; \ - cat $$err 1>&2; \ - fi; \ - done; \ - echo "$$dir: $$passed/$$total tests passed; $$failed/$$total tests failed"; \ - if test $$failed -ne 0; then \ - rval=`expr $$rval + $$failed`; \ - fi; \ - done; \ + AWK=$(AWK) $(SHELL) harness sudoers || rval=`expr $$rval + $$?`; \ + AWK=$(AWK) $(SHELL) harness testsudoers || rval=`expr $$rval + $$?`; \ + AWK=$(AWK) $(SHELL) harness visudo || rval=`expr $$rval + $$?`; \ + AWK=$(AWK) $(SHELL) harness cvtsudoers || rval=`expr $$rval + $$?`; \ exit $$rval; \ fi diff --git a/plugins/sudoers/harness.in b/plugins/sudoers/harness.in new file mode 100755 index 000000000..4d005989b --- /dev/null +++ b/plugins/sudoers/harness.in @@ -0,0 +1,193 @@ +#!/bin/sh +# +# Simple test harness for sudoers tests. +# usage: harness [-v] test_group [test_name ...] +# +srcdir="@srcdir@" +SHELL=@SHELL@ +verbose=0 +rval=0 +ntests=0 +errors=0 + +umask 022 + +if [ "$1" = "-v" ]; then + verbose=1 + shift +fi + +if [ $# -eq 0 ]; then + echo "usage: harness test_group [test_name ...]" >&2 + exit 1 +fi +group="$1" +shift + +if [ ! -d "$srcdir/regress/$group" ]; then + echo "missing test group: $srcdir/regress/$group" >&2 + exit 1 +fi + +case "$group" in +sudoers) + mkdir -p "regress/$group" + if [ $# -eq 0 ]; then + tests= + for t in $srcdir/regress/$group/*.in; do + tests="$tests `basename $t .in`" + done + set -- $tests + fi + while [ $# -ne 0 ]; do + test="$1" + shift + in="$srcdir/regress/sudoers/${test}.in" + out="regress/sudoers/${test}.out" + toke="regress/sudoers/${test}.toke" + json="regress/sudoers/${test}.json" + ldif="regress/sudoers/${test}.ldif" + sudo="regress/sudoers/${test}.sudo" + ldif2sudo="regress/sudoers/${test}.ldif2sudo" + + ./testsudoers -dt <$in >$out 2>$toke || true + ntests=`expr $ntests + 1` + if cmp $out $srcdir/$out.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (parse): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (parse): FAIL" + diff $out $srcdir/$out.ok || true + fi + ntests=`expr $ntests + 1` + if cmp $toke $srcdir/$toke.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (toke): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (toke): FAIL" + diff $toke $srcdir/$toke.ok || true + fi + + ./cvtsudoers -c "" -f json $in >$json 2>/dev/null || true + ntests=`expr $ntests + 1` + if cmp $json $srcdir/$json.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (json): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (json): FAIL" + diff $json $srcdir/$json.ok || true + fi + + SUDOERS_BASE="ou=SUDOers,dc=sudo,dc=ws" \ + ./cvtsudoers -c "" -f ldif < $in >$ldif 2>/dev/null || true + ntests=`expr $ntests + 1` + if cmp $ldif $srcdir/$ldif.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (ldif): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: (ldif) FAIL" + diff $ldif $srcdir/$ldif.ok || true + fi + + ./cvtsudoers -c "" -f sudoers $in >$sudo 2>/dev/null || true + ntests=`expr $ntests + 1` + if ./visudo -qcf $sudo; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (reparse): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: (reparse) FAIL" + ./visudo -cf $sudo || true + fi + + if test -s $srcdir/$ldif.ok; then + ./cvtsudoers -c "" -i ldif -f sudoers $srcdir/$ldif.ok >$ldif2sudo || true + ntests=`expr $ntests + 1` + if cmp $ldif2sudo $srcdir/$ldif2sudo.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (ldif2sudo): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: (ldif2sudo) FAIL" + diff $ldif $srcdir/$ldif.ok || true + fi + fi + done + ${AWK-awk} -v group=$group -v ntests=$ntests -v errors=$errors \ + 'END {printf("%s: %d tests run, %d errors, %d%% success rate\n", group, ntests, errors, (ntests - errors) * 100 / ntests)}' < /dev/null + if test $errors -ne 0; then + rval=`expr $rval + $errors` + fi + ;; +*) + TESTSUDOERS=./testsudoers; export TESTSUDOERS + VISUDO=./visudo; export VISUDO + CVTSUDOERS=./cvtsudoers; export CVTSUDOERS + mkdir -p "regress/$group" + if [ $# -eq 0 ]; then + tests= + for t in $srcdir/regress/$group/*.sh; do + tests="$tests `basename $t .sh`" + done + set -- $tests + fi + while [ $# -ne 0 ]; do + test="$1" + shift + + cmd="$srcdir/regress/$group/${test}.sh" + out="regress/$group/${test}.out" + err="regress/$group/${test}.err" + status=0 + TESTDIR=$srcdir/regress/$group $SHELL $cmd >$out 2>$err || status=$? + ntests=`expr $ntests + 1` + if cmp $out $srcdir/$out.ok >/dev/null; then + if test $status -eq 0; then + if [ $verbose -eq 1 ]; then + echo "$group/$test: OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (exit $status): FAIL" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: FAIL" + diff $out $srcdir/$out.ok || true + fi + if test -s $srcdir/$err.ok; then + ntests=`expr $ntests + 1` + if cmp $err $srcdir/$err.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (stderr): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (stderr): FAIL" + diff $err $srcdir/$err.ok || true + fi + elif test -s $err; then + errors=`expr $errors + 1` + echo "$group/$test (stderr): FAIL" + cat $err 1>&2 + fi + done + ${AWK-awk} -v group=$group -v ntests=$ntests -v errors=$errors \ + 'END {printf("%s: %d tests run, %d errors, %d%% success rate\n", group, ntests, errors, (ntests - errors) * 100 / ntests)}' < /dev/null + if test $errors -ne 0; then + rval=`expr $rval + $errors` + fi + ;; +esac + +exit $rval