summaryrefslogtreecommitdiffstats
path: root/plugins/sudoers/regress/testsudoers
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 13:14:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 13:14:46 +0000
commit025c439e829e0db9ac511cd9c1b8d5fd53475ead (patch)
treefa6986b4690f991613ffb97cea1f6942427baf5d /plugins/sudoers/regress/testsudoers
parentInitial commit. (diff)
downloadsudo-upstream/1.9.15p5.tar.xz
sudo-upstream/1.9.15p5.zip
Adding upstream version 1.9.15p5.upstream/1.9.15p5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/sudoers/regress/testsudoers')
-rw-r--r--plugins/sudoers/regress/testsudoers/group17
-rw-r--r--plugins/sudoers/regress/testsudoers/passwd7
-rw-r--r--plugins/sudoers/regress/testsudoers/test1.out.ok11
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test1.sh15
-rw-r--r--plugins/sudoers/regress/testsudoers/test10.out.ok59
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test10.sh46
-rw-r--r--plugins/sudoers/regress/testsudoers/test11.out.ok25
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test11.sh25
-rw-r--r--plugins/sudoers/regress/testsudoers/test12.out.ok18
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test12.sh19
-rw-r--r--plugins/sudoers/regress/testsudoers/test13.out.ok22
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test13.sh22
-rw-r--r--plugins/sudoers/regress/testsudoers/test14.out.ok18
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test14.sh25
-rw-r--r--plugins/sudoers/regress/testsudoers/test15.out.ok19
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test15.sh24
-rw-r--r--plugins/sudoers/regress/testsudoers/test16.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test16.sh41
-rw-r--r--plugins/sudoers/regress/testsudoers/test17.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test17.sh51
-rw-r--r--plugins/sudoers/regress/testsudoers/test18.out.ok72
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test18.sh40
-rw-r--r--plugins/sudoers/regress/testsudoers/test19.out.ok24
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test19.sh20
-rw-r--r--plugins/sudoers/regress/testsudoers/test2.inc1
-rw-r--r--plugins/sudoers/regress/testsudoers/test2.out.ok29
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test2.sh25
-rw-r--r--plugins/sudoers/regress/testsudoers/test20.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test20.sh18
-rw-r--r--plugins/sudoers/regress/testsudoers/test21.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test21.sh20
-rw-r--r--plugins/sudoers/regress/testsudoers/test22.out.ok11
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test22.sh18
-rw-r--r--plugins/sudoers/regress/testsudoers/test23.out.ok11
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test23.sh17
-rw-r--r--plugins/sudoers/regress/testsudoers/test24.out.ok48
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test24.sh42
-rw-r--r--plugins/sudoers/regress/testsudoers/test25.out.ok59
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test25.sh48
-rw-r--r--plugins/sudoers/regress/testsudoers/test26.out.ok57
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test26.sh50
-rw-r--r--plugins/sudoers/regress/testsudoers/test27.out.ok14
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test27.sh22
-rw-r--r--plugins/sudoers/regress/testsudoers/test28.out.ok125
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test28.sh99
-rw-r--r--plugins/sudoers/regress/testsudoers/test29.out.ok133
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test29.sh71
-rw-r--r--plugins/sudoers/regress/testsudoers/test3.out.ok59
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test3.sh48
-rw-r--r--plugins/sudoers/regress/testsudoers/test30.out.ok133
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test30.sh71
-rw-r--r--plugins/sudoers/regress/testsudoers/test31.out.ok131
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test31.sh71
-rw-r--r--plugins/sudoers/regress/testsudoers/test4.out.ok7
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test4.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test5.out.ok14
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test5.sh31
-rw-r--r--plugins/sudoers/regress/testsudoers/test6.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test6.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test7.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test7.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test8.out.ok29
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test8.sh24
-rw-r--r--plugins/sudoers/regress/testsudoers/test9.out.ok12
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test9.sh15
65 files changed, 2294 insertions, 0 deletions
diff --git a/plugins/sudoers/regress/testsudoers/group b/plugins/sudoers/regress/testsudoers/group
new file mode 100644
index 0000000..f272010
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/group
@@ -0,0 +1,17 @@
+wheel:*:0:root
+daemon:*:1:daemon
+kmem:*:2:root
+sys:*:3:root
+tty:*:4:root
+operator:*:5:root
+bin:*:7:
+wsrc:*:9:
+users:*:10:
+auth:*:11:
+games:*:13:
+staff:*:20:root
+guest:*:31:root
+admin:*:1000:
+fakeshell:*:1001:
+nogroup:*:32766:
+nobody:*:32767:
diff --git a/plugins/sudoers/regress/testsudoers/passwd b/plugins/sudoers/regress/testsudoers/passwd
new file mode 100644
index 0000000..c3d0a9c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/passwd
@@ -0,0 +1,7 @@
+root:*:0:0:Charlie &:/root:/bin/sh
+daemon:*:1:1:The devil himself:/root:/sbin/nologin
+operator:*:2:5:System &:/operator:/sbin/nologin
+bin:*:3:7:Binaries Commands and Source:/:/sbin/nologin
+admin:*:1000:1000:Admin user:/home/admin:/bin/sh
+fakeshell:*:1001:1001:Shell test user:/home/fakeshell:/shell/does/not/exist
+nobody:*:32767:32767:Unprivileged user:/nonexistent:/sbin/nologin
diff --git a/plugins/sudoers/regress/testsudoers/test1.out.ok b/plugins/sudoers/regress/testsudoers/test1.out.ok
new file mode 100644
index 0000000..06c27c4
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test1.out.ok
@@ -0,0 +1,11 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas unmatched
+
+Password required
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test1.sh b/plugins/sudoers/regress/testsudoers/test1.sh
new file mode 100755
index 0000000..495f237
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test1.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Test for NULL dereference with "sudo -g group" when the sudoers rule
+# has no runas user or group listed.
+# This is RedHat bug Bug 667103.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+$TESTSUDOERS -g bin -P ${TESTDIR}/group root id <<EOF
+root ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test10.out.ok b/plugins/sudoers/regress/testsudoers/test10.out.ok
new file mode 100644
index 0000000..94e912e
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test10.out.ok
@@ -0,0 +1,59 @@
+Testing @include of a path with escaped white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing @include of a double-quoted path with white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing #include of a path with escaped white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing #include of a double-quoted path with white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test10.sh b/plugins/sudoers/regress/testsudoers/test10.sh
new file mode 100755
index 0000000..c4f0f2d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test10.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# Test @include of a file with embedded white space
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+# Create test file
+TESTDIR="`pwd`/regress/testsudoers"
+cat >"$TESTDIR/test 10.inc" <<EOF
+root ALL = ALL
+EOF
+
+MYUID=`\ls -lnd "$TESTDIR/test 10.inc" | awk '{print $3}'`
+MYGID=`\ls -lnd "$TESTDIR/test 10.inc" | awk '{print $4}'`
+exec 2>&1
+
+echo "Testing @include of a path with escaped white space"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ @include $TESTDIR/test\ 10.inc
+EOF
+
+echo ""
+echo "Testing @include of a double-quoted path with white space"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ @include "$TESTDIR/test 10.inc"
+EOF
+
+echo ""
+echo "Testing #include of a path with escaped white space"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ #include $TESTDIR/test\ 10.inc
+EOF
+
+echo ""
+echo "Testing #include of a double-quoted path with white space"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ #include "$TESTDIR/test 10.inc"
+EOF
+
+rm -f "$TESTDIR/test 10.inc"
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test11.out.ok b/plugins/sudoers/regress/testsudoers/test11.out.ok
new file mode 100644
index 0000000..ee98540
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test11.out.ok
@@ -0,0 +1,25 @@
+Testing @include with garbage after the path name
+
+sudoers:1:24: syntax error
+@include sudoers.local womp womp
+ ^~~~
+testsudoers: unable to open sudoers.local: No such file or directory
+
+Entries for user root:
+
+Password required
+
+Parse error
+
+Testing #include with garbage after the path name
+
+sudoers:1:24: syntax error
+#include sudoers.local womp womp
+ ^~~~
+testsudoers: unable to open sudoers.local: No such file or directory
+
+Entries for user root:
+
+Password required
+
+Parse error
diff --git a/plugins/sudoers/regress/testsudoers/test11.sh b/plugins/sudoers/regress/testsudoers/test11.sh
new file mode 100755
index 0000000..d52754d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test11.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Test @include with garbage after the path name
+# The standard error output is dup'd to the standard output.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+MYUID=`\ls -ln $TESTDIR/test2.inc | awk '{print $3}'`
+MYGID=`\ls -ln $TESTDIR/test2.inc | awk '{print $4}'`
+
+echo "Testing @include with garbage after the path name"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<EOF 2>&1 | sed 's/\(syntax error\), .*/\1/'
+@include sudoers.local womp womp
+EOF
+
+echo ""
+echo "Testing #include with garbage after the path name"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<EOF 2>&1 | sed 's/\(syntax error\), .*/\1/'
+#include sudoers.local womp womp
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test12.out.ok b/plugins/sudoers/regress/testsudoers/test12.out.ok
new file mode 100644
index 0000000..a28a831
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test12.out.ok
@@ -0,0 +1,18 @@
+Testing sudoers with multiple syntax errors
+
+sudoers:1:20: syntax error
+User_Alias A1 = u1 u2 : A2 = u3, u4
+ ^~
+sudoers:3:26: syntax error
+millert ALL = /fail : foo
+ ^
+sudoers:5:16: syntax error
+root ALL = ALL bar
+ ^~~
+sudoers:7:12: expected a fully-qualified path name
+root ALL = baz
+ ^~~
+
+User_Alias A1 = u1
+
+millert ALL = /fail
diff --git a/plugins/sudoers/regress/testsudoers/test12.sh b/plugins/sudoers/regress/testsudoers/test12.sh
new file mode 100755
index 0000000..8890ca5
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test12.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Test sudoers file with multiple syntax errors
+# The standard error output is dup'd to the standard output.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+echo "Testing sudoers with multiple syntax errors"
+echo ""
+$TESTSUDOERS -d <<EOF 2>&1 | sed 's/\(syntax error\), .*/\1/'
+User_Alias A1 = u1 u2 : A2 = u3, u4
+
+millert ALL = /fail : foo
+
+root ALL = ALL bar
+
+root ALL = baz
+EOF
diff --git a/plugins/sudoers/regress/testsudoers/test13.out.ok b/plugins/sudoers/regress/testsudoers/test13.out.ok
new file mode 100644
index 0000000..bfb9f53
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test13.out.ok
@@ -0,0 +1,22 @@
+Testing alias definitions using reserved words
+
+sudoers:1:12: syntax error, reserved word ALL used as an alias name
+Cmnd_Alias ALL=ALL
+ ^~~
+sudoers:2:12: syntax error, reserved word CHROOT used as an alias name
+Cmnd_Alias CHROOT=foo
+ ^~~~~~
+sudoers:3:12: syntax error, reserved word CMND_TIMEOUT used as an alias name
+User_Alias TIMEOUT=foo
+ ^~~~~~~
+sudoers:4:13: syntax error, reserved word CWD used as an alias name
+Runas_Alias CWD=bar
+ ^~~
+sudoers:5:12: syntax error, reserved word NOTBEFORE used as an alias name
+Host_Alias NOTBEFORE=baz
+ ^~~~~~~~~
+sudoers:6:12: syntax error, reserved word NOTAFTER used as an alias name
+Host_Alias NOTAFTER=biff
+ ^~~~~~~~
+
+root ALL = ALL
diff --git a/plugins/sudoers/regress/testsudoers/test13.sh b/plugins/sudoers/regress/testsudoers/test13.sh
new file mode 100755
index 0000000..d9c3d0c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test13.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Test sudoers file with reserved words as alias names.
+# The standard error output is dup'd to the standard output.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+echo "Testing alias definitions using reserved words"
+echo ""
+$TESTSUDOERS -d <<EOF 2>&1
+Cmnd_Alias ALL=ALL
+Cmnd_Alias CHROOT=foo
+User_Alias TIMEOUT=foo
+Runas_Alias CWD=bar
+Host_Alias NOTBEFORE=baz
+Host_Alias NOTAFTER=biff
+
+root ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test14.out.ok b/plugins/sudoers/regress/testsudoers/test14.out.ok
new file mode 100644
index 0000000..add1bb2
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test14.out.ok
@@ -0,0 +1,18 @@
+
+Testing user privilege without a newline
+
+Parses OK
+
+millert ALL = ALL
+
+Testing alias without a newline
+
+Parses OK
+
+Cmnd_Alias FOO = /bin/bar
+
+Testing Defaults without a newline
+
+Parses OK
+
+Defaults log_output
diff --git a/plugins/sudoers/regress/testsudoers/test14.sh b/plugins/sudoers/regress/testsudoers/test14.sh
new file mode 100755
index 0000000..7739c67
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test14.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Test entries with no trailing newline.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+echo ""
+echo "Testing user privilege without a newline"
+echo ""
+printf "millert ALL = ALL" | $TESTSUDOERS -d
+
+echo ""
+echo "Testing alias without a newline"
+echo ""
+printf "Cmnd_Alias FOO=/bin/bar" | $TESTSUDOERS -d
+
+echo ""
+echo "Testing Defaults without a newline"
+echo ""
+printf "Defaults log_output" | $TESTSUDOERS -d
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test15.out.ok b/plugins/sudoers/regress/testsudoers/test15.out.ok
new file mode 100644
index 0000000..cc4361d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test15.out.ok
@@ -0,0 +1,19 @@
+Testing @include of a file with a missing newline
+
+Parses OK
+
+Entries for user root:
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd unmatched
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test15.sh b/plugins/sudoers/regress/testsudoers/test15.sh
new file mode 100755
index 0000000..a4596cd
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test15.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# Test @include of a file with a missing newline
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+# Create test file
+TESTDIR="`pwd`/regress/testsudoers"
+printf "root ALL = ALL" >"$TESTDIR/test15.inc"
+
+MYUID=`\ls -lnd "$TESTDIR/test15.inc" | awk '{print $3}'`
+MYGID=`\ls -lnd "$TESTDIR/test15.inc" | awk '{print $4}'`
+exec 2>&1
+
+echo "Testing @include of a file with a missing newline"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ @include $TESTDIR/test15.inc
+ ALL ALL = /usr/bin/id
+EOF
+
+rm -f "$TESTDIR/test15.inc"
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test16.out.ok b/plugins/sudoers/regress/testsudoers/test16.out.ok
new file mode 100644
index 0000000..3c4e7fa
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test16.out.ok
@@ -0,0 +1,12 @@
+Parses OK
+
+Entries for user root:
+
+ALL = (ALL) ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test16.sh b/plugins/sudoers/regress/testsudoers/test16.sh
new file mode 100755
index 0000000..507bdd4
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test16.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# Test to exercise Bug #994, a crash matching sudoCommand ALL.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+$TESTSUDOERS -i ldif root id <<-EOF
+dn: dc=sudo,dc=ws
+objectClass: dcObject
+objectClass: organization
+dc: bigwheel
+o: Big Wheel
+description: Big Wheel
+
+# Organizational Role for Directory Manager
+dn: cn=Manager,dc=sudo,dc=ws
+objectClass: organizationalRole
+cn: Manager
+description: Directory Manager
+
+# SUDOers, sudo.ws
+dn: ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: organizationalUnit
+description: SUDO Configuration Subtree
+ou: SUDOers
+
+# root, SUDOers, sudo.ws
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAs: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOrder: 10
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test17.out.ok b/plugins/sudoers/regress/testsudoers/test17.out.ok
new file mode 100644
index 0000000..56c4715
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test17.out.ok
@@ -0,0 +1,12 @@
+Parses OK
+
+Entries for user root:
+
+ALL = (ALL) sha224:fIoq2MAfM/PZKTbkn9RE4VZ8YHjwnwTgE28Hxw== ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test17.sh b/plugins/sudoers/regress/testsudoers/test17.sh
new file mode 100755
index 0000000..b98b907
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test17.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Test that digest matching works with LDAP sudoCommand: ALL
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+# Create test command with known digest
+TESTDIR="`pwd`/regress/testsudoers"
+cat >"$TESTDIR/hello" <<EOF
+#!/bin/sh
+echo Hello World
+EOF
+chmod 755 "$TESTDIR/hello"
+SHA224_DIGEST="fIoq2MAfM/PZKTbkn9RE4VZ8YHjwnwTgE28Hxw=="
+
+$TESTSUDOERS -i ldif root "${TESTDIR}/hello" <<-EOF
+dn: dc=sudo,dc=ws
+objectClass: dcObject
+objectClass: organization
+dc: bigwheel
+o: Big Wheel
+description: Big Wheel
+
+# Organizational Role for Directory Manager
+dn: cn=Manager,dc=sudo,dc=ws
+objectClass: organizationalRole
+cn: Manager
+description: Directory Manager
+
+# SUDOers, sudo.ws
+dn: ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: organizationalUnit
+description: SUDO Configuration Subtree
+ou: SUDOers
+
+# root, SUDOers, sudo.ws
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAs: ALL
+sudoHost: ALL
+sudoCommand: sha224:$SHA224_DIGEST ALL
+sudoOrder: 10
+EOF
+
+rm -f "$TESTDIR/hello"
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test18.out.ok b/plugins/sudoers/regress/testsudoers/test18.out.ok
new file mode 100644
index 0000000..c497a7a
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test18.out.ok
@@ -0,0 +1,72 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ^/bin/ls$ ^-[lAt]$
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = ^/bin/cat$ /var/log/*
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/cat ^/var/log/[^/]+$
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/*at ^/var/log/[^/]+$
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /usr/bin/grep \^foo$
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = sudoedit ^/etc/(motd|issue|hosts)$
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test18.sh b/plugins/sudoers/regress/testsudoers/test18.sh
new file mode 100755
index 0000000..645b9a5
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test18.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Test regular expressions
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+# Command and args: regex
+$TESTSUDOERS root /bin/ls -l <<'EOF'
+root ALL = ^/bin/ls$ ^-[lAt]$
+EOF
+
+# Command: regex, args: wildcard
+$TESTSUDOERS root /bin/cat /var/log/syslog <<'EOF'
+root ALL = ^/bin/cat$ /var/log/*
+EOF
+
+# Command: path, args: regex
+$TESTSUDOERS root /bin/cat /var/log/authlog <<'EOF'
+root ALL = /bin/cat ^/var/log/[^/]+$
+EOF
+
+# Command: wildcard, args: regex
+$TESTSUDOERS root /bin/cat /var/log/mail <<'EOF'
+root ALL = /bin/*at ^/var/log/[^/]+$
+EOF
+
+# Command: path, args: args start with escaped ^
+$TESTSUDOERS root /usr/bin/grep '^foo$' <<'EOF'
+root ALL = /usr/bin/grep \^foo$
+EOF
+
+# Command: sudoedit, args: regex
+$TESTSUDOERS root sudoedit /etc/motd <<'EOF'
+root ALL = sudoedit ^/etc/(motd|issue|hosts)$
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test19.out.ok b/plugins/sudoers/regress/testsudoers/test19.out.ok
new file mode 100644
index 0000000..db2142d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test19.out.ok
@@ -0,0 +1,24 @@
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls ""
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls ""
+ host allowed
+ runas allowed
+ cmnd unmatched
+
+Password required
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test19.sh b/plugins/sudoers/regress/testsudoers/test19.sh
new file mode 100755
index 0000000..113eb2a
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test19.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# Verify that "" in sudoers does not match a literal "" on the command line.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+# This should succeed
+$TESTSUDOERS root /bin/ls <<'EOF'
+root ALL = /bin/ls ""
+EOF
+
+# This should fail
+$TESTSUDOERS root /bin/ls '""' <<'EOF'
+root ALL = /bin/ls ""
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test2.inc b/plugins/sudoers/regress/testsudoers/test2.inc
new file mode 100644
index 0000000..52ca040
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test2.inc
@@ -0,0 +1 @@
+root ALL = ALL
diff --git a/plugins/sudoers/regress/testsudoers/test2.out.ok b/plugins/sudoers/regress/testsudoers/test2.out.ok
new file mode 100644
index 0000000..a017d8a
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test2.out.ok
@@ -0,0 +1,29 @@
+Testing @include
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing #include
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test2.sh b/plugins/sudoers/regress/testsudoers/test2.sh
new file mode 100755
index 0000000..0b0b3f8
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test2.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Test @include facility
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+MYUID=`\ls -ln $TESTDIR/test2.inc | awk '{print $3}'`
+MYGID=`\ls -ln $TESTDIR/test2.inc | awk '{print $4}'`
+exec 2>&1
+
+echo "Testing @include"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<EOF
+@include $TESTDIR/test2.inc
+EOF
+
+echo ""
+echo "Testing #include"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<EOF
+#include $TESTDIR/test2.inc
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test20.out.ok b/plugins/sudoers/regress/testsudoers/test20.out.ok
new file mode 100644
index 0000000..6a8e451
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test20.out.ok
@@ -0,0 +1,12 @@
+Parses OK
+
+Entries for user root:
+
+ALL = CHROOT=/ /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test20.sh b/plugins/sudoers/regress/testsudoers/test20.sh
new file mode 100755
index 0000000..4325175
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test20.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Verify CHROOT and CWD support
+# This will catch an unpatched double-free in set_cmnd_path() under ASAN.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+# Exercise double free of user_cmnd in set_cmnd_path() under ASAN.
+# We need more than one rule where the last rule matches and has CHROOT.
+$TESTSUDOERS root /bin/ls <<'EOF'
+root ALL = CWD=/ /bin/pwd
+root ALL = CHROOT=/ /bin/ls
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test21.out.ok b/plugins/sudoers/regress/testsudoers/test21.out.ok
new file mode 100644
index 0000000..391b668
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test21.out.ok
@@ -0,0 +1,12 @@
+Parses OK
+
+Entries for user admin:
+
+ALL = (USERALIAS : GROUPALIAS) /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test21.sh b/plugins/sudoers/regress/testsudoers/test21.sh
new file mode 100755
index 0000000..714caf1
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test21.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# Verify that a Runas_Alias works in both user and group lists.
+# This tests a bug fixed in sudo 1.9.14.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+# The user in USERALIAS must *not* belong to the group in GROUPALIAS
+# in the group or passwd file in order to reproduce the bug.
+$TESTSUDOERS -u root -g bin -p ${TESTDIR}/passwd -P ${TESTDIR}/group \
+ admin /bin/ls <<'EOF'
+Runas_Alias USERALIAS = root
+Runas_Alias GROUPALIAS = bin
+admin ALL = (USERALIAS : GROUPALIAS) /bin/ls
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test22.out.ok b/plugins/sudoers/regress/testsudoers/test22.out.ok
new file mode 100644
index 0000000..54f273f
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test22.out.ok
@@ -0,0 +1,11 @@
+Parses OK
+
+Entries for user admin:
+
+ALL = /bin/ls
+ host allowed
+ runas unmatched
+
+Password required
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test22.sh b/plugins/sudoers/regress/testsudoers/test22.sh
new file mode 100755
index 0000000..9d4dbcb
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test22.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Verify that a user is only allowed to run commands with a group
+# that is specified by sudoers (or that the runas user is a member of).
+# This tests a bug fixed in sudo 1.9.14.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+# The root user must *not* belong to the group specified below.
+$TESTSUDOERS -u root -g bin -p ${TESTDIR}/passwd -P ${TESTDIR}/group \
+ admin /bin/ls <<'EOF'
+admin ALL = /bin/ls
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test23.out.ok b/plugins/sudoers/regress/testsudoers/test23.out.ok
new file mode 100644
index 0000000..2e99ac8
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test23.out.ok
@@ -0,0 +1,11 @@
+Parses OK
+
+Entries for user admin:
+
+ALL = (root) /bin/ls
+ host allowed
+ runas unmatched
+
+Password required
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test23.sh b/plugins/sudoers/regress/testsudoers/test23.sh
new file mode 100755
index 0000000..a790c6a
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test23.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Verify that a user is not allowed to run commands with their own
+# user and group if sudoers doesn't explicitly permit it.
+# This tests a bug fixed in sudo 1.9.14.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+$TESTSUDOERS -u admin -g admin -p ${TESTDIR}/passwd -P ${TESTDIR}/group \
+ admin /bin/ls <<'EOF'
+admin ALL = (root) /bin/ls
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test24.out.ok b/plugins/sudoers/regress/testsudoers/test24.out.ok
new file mode 100644
index 0000000..0a38de3
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test24.out.ok
@@ -0,0 +1,48 @@
+Parses OK
+
+Entries for user root:
+
+ALL = NOTBEFORE=20170214083000Z /bin/ls
+ host allowed
+ date allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = NOTBEFORE=20170214083001Z /bin/ls
+ host allowed
+ date denied
+
+Password required
+
+Command unmatched
+Parses OK
+
+Entries for user root:
+
+ALL = NOTAFTER=20170214083000Z /bin/ls
+ host allowed
+ date allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = NOTAFTER=20170214083000Z /bin/ls
+ host allowed
+ date denied
+
+Password required
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test24.sh b/plugins/sudoers/regress/testsudoers/test24.sh
new file mode 100755
index 0000000..8be4ebc
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test24.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# Verify that NOTBEFORE and NOTAFTER work as expected.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+retval=0
+
+$TESTSUDOERS -T 20170214083000Z root /bin/ls <<'EOF'
+root ALL = NOTBEFORE=20170214083000Z /bin/ls
+EOF
+if [ $? -ne 0 ]; then
+ retval=$?
+fi
+
+# expect failure
+$TESTSUDOERS -T 20170214083000Z root /bin/ls <<'EOF'
+root ALL = NOTBEFORE=20170214083001Z /bin/ls
+EOF
+if [ $? -eq 0 ]; then
+ retval=1
+fi
+
+$TESTSUDOERS -T 20170214083000Z root /bin/ls <<'EOF'
+root ALL = NOTAFTER=20170214083000Z /bin/ls
+EOF
+if [ $? -ne 0 ]; then
+ retval=$?
+fi
+
+# expect failure
+$TESTSUDOERS -T 20170214083001Z root /bin/ls <<'EOF'
+root ALL = NOTAFTER=20170214083000Z /bin/ls
+EOF
+if [ $? -eq 0 ]; then
+ retval=1
+fi
+
+exit $retval
diff --git a/plugins/sudoers/regress/testsudoers/test25.out.ok b/plugins/sudoers/regress/testsudoers/test25.out.ok
new file mode 100644
index 0000000..d23bdb2
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test25.out.ok
@@ -0,0 +1,59 @@
+A simple sudoers rule should not allow the user to set the cwd:
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+User root is not allowed to change directory to /
+
+Password required
+
+Command denied
+
+User cannot override the sudoers cwd:
+Parses OK
+
+Entries for user root:
+
+ALL = CWD=/some/where/else /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+User root is not allowed to change directory to /
+
+Password required
+
+Command denied
+
+User can set cwd if sudoers rule sets cwd to '*':
+Parses OK
+
+Entries for user root:
+
+ALL = CWD=* /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+User can set cwd runcwd Defaults is '*':
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test25.sh b/plugins/sudoers/regress/testsudoers/test25.sh
new file mode 100755
index 0000000..a3c395c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test25.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Test user-specified cwd handling
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+cd /
+
+retval=0
+
+# Sudo used to allow the user to set the cwd to the current value.
+# Now, a cwd must be explicitly set in sudoers to use the -D option.
+printf "A simple sudoers rule should not allow the user to set the cwd:\n"
+$TESTSUDOERS -D / root /bin/ls <<'EOF'
+root ALL = /bin/ls
+EOF
+if [ $? -eq 0 ]; then
+ retval=1
+fi
+
+printf "\nUser cannot override the sudoers cwd:\n"
+$TESTSUDOERS -D / root /bin/ls <<'EOF'
+root ALL = CWD=/some/where/else /bin/ls
+EOF
+if [ $? -eq 0 ]; then
+ retval=1
+fi
+
+printf "\nUser can set cwd if sudoers rule sets cwd to '*':\n"
+$TESTSUDOERS -D /usr root /bin/ls <<'EOF'
+root ALL = CWD=* /bin/ls
+EOF
+if [ $? -ne 0 ]; then
+ retval=$?
+fi
+
+printf "\nUser can set cwd runcwd Defaults is '*':\n"
+$TESTSUDOERS -D /usr root /bin/ls <<'EOF'
+Defaults runcwd = "*"
+root ALL = /bin/ls
+EOF
+if [ $? -ne 0 ]; then
+ retval=$?
+fi
+
+exit $retval
diff --git a/plugins/sudoers/regress/testsudoers/test26.out.ok b/plugins/sudoers/regress/testsudoers/test26.out.ok
new file mode 100644
index 0000000..281817c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test26.out.ok
@@ -0,0 +1,57 @@
+A simple sudoers rule should not allow the user to chroot:
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+User root is not allowed to change root directory to /
+
+Password required
+
+Command denied
+
+User cannot override the sudoers chroot:
+Parses OK
+
+Entries for user root:
+
+ALL = CHROOT=/some/where/else /bin/ls
+ host allowed
+ runas allowed
+ cmnd unmatched
+
+Password required
+
+Command unmatched
+
+User can chroot if sudoers rule sets chroot to '*':
+Parses OK
+
+Entries for user root:
+
+ALL = CHROOT=* /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+User can chroot if runchroot Defaults is '*':
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test26.sh b/plugins/sudoers/regress/testsudoers/test26.sh
new file mode 100755
index 0000000..bef55da
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test26.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# Test user-specified chroot handling
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+cd /
+
+retval=0
+
+printf "A simple sudoers rule should not allow the user to chroot:\n"
+$TESTSUDOERS -R / root /bin/ls <<'EOF'
+root ALL = /bin/ls
+EOF
+if [ $? -eq 0 ]; then
+ retval=1
+fi
+
+# Because command_matches() uses the per-rule CHROOT, this results in
+# an unmatched rule instead of a matched rule that is rejected later.
+# This is different from the CWD checking which is performed after
+# matching is done.
+printf "\nUser cannot override the sudoers chroot:\n"
+$TESTSUDOERS -R / root /bin/ls <<'EOF'
+root ALL = CHROOT=/some/where/else /bin/ls
+EOF
+if [ $? -eq 0 ]; then
+ retval=1
+fi
+
+printf "\nUser can chroot if sudoers rule sets chroot to '*':\n"
+$TESTSUDOERS -R /usr root /bin/ls <<'EOF'
+root ALL = CHROOT=* /bin/ls
+EOF
+if [ $? -ne 0 ]; then
+ retval=$?
+fi
+
+printf "\nUser can chroot if runchroot Defaults is '*':\n"
+$TESTSUDOERS -R /usr root /bin/ls <<'EOF'
+Defaults runchroot = "*"
+root ALL = /bin/ls
+EOF
+if [ $? -ne 0 ]; then
+ retval=$?
+fi
+
+exit $retval
diff --git a/plugins/sudoers/regress/testsudoers/test27.out.ok b/plugins/sudoers/regress/testsudoers/test27.out.ok
new file mode 100644
index 0000000..73c06b7
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test27.out.ok
@@ -0,0 +1,14 @@
+Parses OK
+
+Entries for user admin:
+
+ALL = (ALL) /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Invalid shell for user fakeshell: /shell/does/not/exist
+
+Password required
+
+Command denied
diff --git a/plugins/sudoers/regress/testsudoers/test27.sh b/plugins/sudoers/regress/testsudoers/test27.sh
new file mode 100755
index 0000000..8733bb8
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test27.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Verify that runas_check_shell works as expected.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+# This should fail due to fakeshell's shell
+$TESTSUDOERS -u fakeshell -p ${TESTDIR}/passwd -P ${TESTDIR}/group \
+ admin /bin/ls <<'EOF'
+Defaults runas_check_shell
+admin ALL = (ALL) /bin/ls
+EOF
+
+# Expected failure
+if [ $? -eq 0 ]; then
+ exit 1
+else
+ exit 0
+fi
diff --git a/plugins/sudoers/regress/testsudoers/test28.out.ok b/plugins/sudoers/regress/testsudoers/test28.out.ok
new file mode 100644
index 0000000..188d8de
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test28.out.ok
@@ -0,0 +1,125 @@
+This should match the 'ALL=ALL' rule.
+Parses OK
+
+Entries for user admin:
+
+ALL = (admin : staff) NOPASSWD: ALL
+ host allowed
+ runas unmatched
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+This should match the 'ALL=ALL' rule.
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+This should match the 'ALL=(:staff) NOPASSWD: ALL' rule.
+Parses OK
+
+Entries for user admin:
+
+ALL = (admin : staff) NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+This should match the 'ALL=(:staff) NOPASSWD: ALL' rule.
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas unmatched
+
+ALL = (admin : staff) NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+This should match the 'ALL=(:staff) NOPASSWD: ALL' rule.
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas unmatched
+
+ALL = (admin : staff) NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+This should match the 'ALL=(:staff) NOPASSWD: ALL' rule.
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas unmatched
+
+ALL = (admin : staff) NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+This should not match any rules.
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas unmatched
+
+ALL = (admin : staff) NOPASSWD: ALL
+ host allowed
+ runas unmatched
+
+Password required
+
+Command unmatched
+
+This should not match any rules.
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas unmatched
+
+ALL = (admin : users) NOPASSWD: ALL
+ host allowed
+ runas unmatched
+
+Password required
+
+Command unmatched
diff --git a/plugins/sudoers/regress/testsudoers/test28.sh b/plugins/sudoers/regress/testsudoers/test28.sh
new file mode 100755
index 0000000..0465531
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test28.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+#
+# Verify that a rule with an empty Runas user matches correctly.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+status=0
+
+echo "This should match the 'ALL=ALL' rule."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group \
+ admin /bin/ls <<'EOF'
+admin ALL = ALL
+ALL ALL=(:staff) NOPASSWD: ALL
+EOF
+if [ $? -ne 0 ]; then
+ status=1
+fi
+
+echo ""
+echo "This should match the 'ALL=ALL' rule."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group \
+ admin /bin/ls <<'EOF'
+ALL ALL=(:staff) NOPASSWD: ALL
+admin ALL = ALL
+EOF
+if [ $? -ne 0 ]; then
+ status=1
+fi
+
+echo ""
+echo "This should match the 'ALL=(:staff) NOPASSWD: ALL' rule."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -g staff \
+ admin /bin/ls <<'EOF'
+admin ALL = ALL
+ALL ALL=(:staff) NOPASSWD: ALL
+EOF
+if [ $? -ne 0 ]; then
+ status=1
+fi
+
+echo ""
+echo "This should match the 'ALL=(:staff) NOPASSWD: ALL' rule."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -g staff \
+ admin /bin/ls <<'EOF'
+ALL ALL=(:staff) NOPASSWD: ALL
+admin ALL = ALL
+EOF
+if [ $? -ne 0 ]; then
+ status=1
+fi
+
+echo ""
+echo "This should match the 'ALL=(:staff) NOPASSWD: ALL' rule."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -u admin \
+ admin /bin/ls <<'EOF'
+ALL ALL=(:staff) NOPASSWD: ALL
+admin ALL = ALL
+EOF
+if [ $? -ne 0 ]; then
+ status=1
+fi
+
+echo ""
+echo "This should match the 'ALL=(:staff) NOPASSWD: ALL' rule."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -u admin -g staff \
+ admin /bin/ls <<'EOF'
+ALL ALL=(:staff) NOPASSWD: ALL
+admin ALL = ALL
+EOF
+if [ $? -ne 0 ]; then
+ status=1
+fi
+
+echo ""
+echo "This should not match any rules."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -g guest \
+ admin /bin/ls <<'EOF'
+ALL ALL=(:staff) NOPASSWD: ALL
+admin ALL = ALL
+EOF
+if [ $? -eq 0 ]; then
+ status=1
+fi
+
+echo ""
+echo "This should not match any rules."
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -u root -g users \
+ admin /bin/ls <<'EOF'
+ALL ALL=(:users) NOPASSWD: ALL
+admin ALL = ALL
+EOF
+if [ $? -eq 0 ]; then
+ status=1
+fi
+
+exit $status
diff --git a/plugins/sudoers/regress/testsudoers/test29.out.ok b/plugins/sudoers/regress/testsudoers/test29.out.ok
new file mode 100644
index 0000000..bf145c7
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test29.out.ok
@@ -0,0 +1,133 @@
+listpw = all, 'sudo -l' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+listpw = all, 'sudo -l' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+listpw = all, 'sudo -l' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = NOPASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+listpw = always, 'sudo -l' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+listpw = any, 'sudo -l' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+listpw = any, 'sudo -l' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = NOPASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+listpw = any, 'sudo -l' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+listpw = never, 'sudo -l' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = PASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test29.sh b/plugins/sudoers/regress/testsudoers/test29.sh
new file mode 100755
index 0000000..802b812
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test29.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# Exercise listpw Defaults settings.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+status=0
+
+echo "listpw = all, 'sudo -l' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = all
+admin ALL = NOPASSWD: ALL
+admin ALL = /usr/bin/id
+EOF
+
+echo ""
+echo "listpw = all, 'sudo -l' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = all
+admin ALL = /usr/bin/id
+admin ALL = NOPASSWD: ALL
+EOF
+
+echo ""
+echo "listpw = all, 'sudo -l' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = all
+admin ALL = NOPASSWD: ALL
+admin ALL = NOPASSWD: /usr/bin/id
+EOF
+
+echo ""
+echo "listpw = always, 'sudo -l' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = always
+admin ALL = NOPASSWD: ALL
+EOF
+
+echo ""
+echo "listpw = any, 'sudo -l' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = any
+admin ALL = ALL
+admin ALL = /usr/bin/id
+EOF
+
+echo ""
+echo "listpw = any, 'sudo -l' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = any
+admin ALL = ALL
+admin ALL = NOPASSWD: /usr/bin/id
+EOF
+
+echo ""
+echo "listpw = any, 'sudo -l' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = any
+admin ALL = NOPASSWD: /usr/bin/id
+admin ALL = ALL
+EOF
+
+echo ""
+echo "listpw = never, 'sudo -l' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin <<'EOF'
+Defaults listpw = never
+admin ALL = PASSWD: /usr/bin/id
+EOF
diff --git a/plugins/sudoers/regress/testsudoers/test3.out.ok b/plugins/sudoers/regress/testsudoers/test3.out.ok
new file mode 100644
index 0000000..fc61e3d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test3.out.ok
@@ -0,0 +1,59 @@
+Testing @includedir of an unquoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing @includedir of a double-quoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing #includedir of an unquoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing #includedir of a double-quoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test3.sh b/plugins/sudoers/regress/testsudoers/test3.sh
new file mode 100755
index 0000000..d166de9
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test3.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Test @includedir facility
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+TESTDIR="`pwd`/regress/testsudoers"
+# make sure include file is owned by current user
+rm -rf "$TESTDIR/test3.d"
+mkdir "$TESTDIR/test3.d"
+cat >"$TESTDIR/test3.d/root" <<-EOF
+ root ALL = ALL
+EOF
+
+MYUID=`\ls -lnd $TESTDIR/test3.d | awk '{print $3}'`
+MYGID=`\ls -lnd $TESTDIR/test3.d | awk '{print $4}'`
+exec 2>&1
+
+echo "Testing @includedir of an unquoted path"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ @includedir $TESTDIR/test3.d
+EOF
+
+echo ""
+echo "Testing @includedir of a double-quoted path"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ @includedir "$TESTDIR/test3.d"
+EOF
+
+echo ""
+echo "Testing #includedir of an unquoted path"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ #includedir $TESTDIR/test3.d
+EOF
+
+echo ""
+echo "Testing #includedir of a double-quoted path"
+echo ""
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<-EOF
+ #includedir "$TESTDIR/test3.d"
+EOF
+
+rm -rf "$TESTDIR/test3.d"
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test30.out.ok b/plugins/sudoers/regress/testsudoers/test30.out.ok
new file mode 100644
index 0000000..5763072
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test30.out.ok
@@ -0,0 +1,133 @@
+verifypw = all, 'sudo -v' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+verifypw = all, 'sudo -v' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+verifypw = all, 'sudo -v' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = NOPASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+verifypw = always, 'sudo -v' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+verifypw = any, 'sudo -v' should require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+verifypw = any, 'sudo -v' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = NOPASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+verifypw = any, 'sudo -v' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+verifypw = never, 'sudo -v' should not require a password
+Parses OK
+
+Entries for user admin:
+
+ALL = PASSWD: /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test30.sh b/plugins/sudoers/regress/testsudoers/test30.sh
new file mode 100755
index 0000000..57b30ae
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test30.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# Exercise verifypw Defaults settings.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+status=0
+
+echo "verifypw = all, 'sudo -v' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = all
+admin ALL = NOPASSWD: ALL
+admin ALL = /usr/bin/id
+EOF
+
+echo ""
+echo "verifypw = all, 'sudo -v' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = all
+admin ALL = /usr/bin/id
+admin ALL = NOPASSWD: ALL
+EOF
+
+echo ""
+echo "verifypw = all, 'sudo -v' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = all
+admin ALL = NOPASSWD: ALL
+admin ALL = NOPASSWD: /usr/bin/id
+EOF
+
+echo ""
+echo "verifypw = always, 'sudo -v' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = always
+admin ALL = NOPASSWD: ALL
+EOF
+
+echo ""
+echo "verifypw = any, 'sudo -v' should require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = any
+admin ALL = ALL
+admin ALL = /usr/bin/id
+EOF
+
+echo ""
+echo "verifypw = any, 'sudo -v' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = any
+admin ALL = ALL
+admin ALL = NOPASSWD: /usr/bin/id
+EOF
+
+echo ""
+echo "verifypw = any, 'sudo -v' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = any
+admin ALL = NOPASSWD: /usr/bin/id
+admin ALL = ALL
+EOF
+
+echo ""
+echo "verifypw = never, 'sudo -v' should not require a password"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -v admin <<'EOF'
+Defaults verifypw = never
+admin ALL = PASSWD: /usr/bin/id
+EOF
diff --git a/plugins/sudoers/regress/testsudoers/test31.out.ok b/plugins/sudoers/regress/testsudoers/test31.out.ok
new file mode 100644
index 0000000..04b2347
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test31.out.ok
@@ -0,0 +1,131 @@
+'sudo -U root -l' with no matching rules
+Parses OK
+
+Entries for user admin:
+
+Password required
+
+Command denied
+
+'sudo -U root -l' with a matching ALL=ALL rule
+Parses OK
+
+Entries for user admin:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+'sudo -U root -l' with a matching list rule
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: list
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Command allowed
+
+'sudo -U root -l' without a matching list rule
+Parses OK
+
+Entries for user admin:
+
+ALL = (operator) list
+ host allowed
+ runas unmatched
+
+Password required
+
+Command denied
+
+'sudo -U root -l' with a negated list rule
+Parses OK
+
+Entries for user admin:
+
+ALL = !list
+ host allowed
+ runas allowed
+ cmnd denied
+
+Password required
+
+Command denied
+
+'sudo -U root -l' with a list rule that is later negated
+Parses OK
+
+Entries for user admin:
+
+ALL = NOPASSWD: list, !list
+ host allowed
+ runas allowed
+ cmnd allowed
+ runas allowed
+ cmnd denied
+
+Command denied
+
+'sudo -l command' with a matching command
+Parses OK
+
+Entries for user admin:
+
+ALL = /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+'sudo -l command' without a matching command
+Parses OK
+
+Entries for user admin:
+
+ALL = /bin/ls
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+'sudo -U root -l command' without list privileges
+Parses OK
+
+Entries for user admin:
+
+ALL = /usr/bin/id
+ host allowed
+ runas allowed
+ cmnd unmatched
+
+Password required
+
+Command denied
+
+'sudo -U root -l command' with list privileges
+Parses OK
+
+Entries for user admin:
+
+ALL = list
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test31.sh b/plugins/sudoers/regress/testsudoers/test31.sh
new file mode 100755
index 0000000..a40906d
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test31.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# Exercise "sudo -U user -l [command]"
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+
+status=0
+
+echo "'sudo -U root -l' with no matching rules"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin <<'EOF'
+root ALL = ALL
+EOF
+
+echo ""
+echo "'sudo -U root -l' with a matching ALL=ALL rule"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin <<'EOF'
+admin ALL = ALL
+EOF
+
+echo ""
+echo "'sudo -U root -l' with a matching list rule"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin <<'EOF'
+admin ALL = NOPASSWD: list
+EOF
+
+echo ""
+echo "'sudo -U root -l' without a matching list rule"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin <<'EOF'
+admin ALL = (operator) list
+EOF
+
+echo ""
+echo "'sudo -U root -l' with a negated list rule"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin <<'EOF'
+admin ALL = !list
+EOF
+
+echo ""
+echo "'sudo -U root -l' with a list rule that is later negated"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin <<'EOF'
+admin ALL = NOPASSWD: list, !list
+EOF
+
+echo ""
+echo "'sudo -l command' with a matching command"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin /bin/ls <<'EOF'
+admin ALL = /bin/ls
+EOF
+
+echo ""
+echo "'sudo -l command' without a matching command"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -l admin /usr/bin/id <<'EOF'
+admin ALL = /bin/ls
+EOF
+
+echo ""
+echo "'sudo -U root -l command' without list privileges"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin /bin/ls <<'EOF'
+root ALL = ALL
+admin ALL = /usr/bin/id
+EOF
+
+echo ""
+echo "'sudo -U root -l command' with list privileges"
+$TESTSUDOERS -p ${TESTDIR}/passwd -P ${TESTDIR}/group -L root admin /bin/ls <<'EOF'
+root ALL = ALL
+admin ALL = list
+EOF
diff --git a/plugins/sudoers/regress/testsudoers/test4.out.ok b/plugins/sudoers/regress/testsudoers/test4.out.ok
new file mode 100644
index 0000000..4987d8b
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test4.out.ok
@@ -0,0 +1,7 @@
+testsudoers: test2.inc should be owned by uid 1
+
+Entries for user root:
+
+Password required
+
+Parse error
diff --git a/plugins/sudoers/regress/testsudoers/test4.sh b/plugins/sudoers/regress/testsudoers/test4.sh
new file mode 100755
index 0000000..4d496c7
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test4.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Test sudoers owner check
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+$TESTSUDOERS -U 1 root id <<EOF
+@include $TESTDIR/test2.inc
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test5.out.ok b/plugins/sudoers/regress/testsudoers/test5.out.ok
new file mode 100644
index 0000000..3bd1747
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test5.out.ok
@@ -0,0 +1,14 @@
+testsudoers: test5.inc is world writable
+
+Entries for user root:
+
+Password required
+
+Parse error
+testsudoers: test5.inc should be owned by gid 4294967294
+
+Entries for user root:
+
+Password required
+
+Parse error
diff --git a/plugins/sudoers/regress/testsudoers/test5.sh b/plugins/sudoers/regress/testsudoers/test5.sh
new file mode 100755
index 0000000..317ad98
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test5.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Test sudoers file mode check
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+# Create test file
+TESTFILE="`pwd`/regress/testsudoers/test5.inc"
+cat >"$TESTFILE" <<EOF
+root ALL = ALL
+EOF
+
+MYUID=`\ls -ln $TESTFILE | awk '{print $3}'`
+MYGID=`\ls -ln $TESTFILE | awk '{print $4}'`
+exec 2>&1
+
+# Test world writable
+chmod 666 $TESTFILE
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<EOF
+@include $TESTFILE
+EOF
+
+# Test group writable
+chmod 664 $TESTFILE
+$TESTSUDOERS -U $MYUID -G -2 root id <<EOF
+@include $TESTFILE
+EOF
+
+rm -f $TESTFILE
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test6.out.ok b/plugins/sudoers/regress/testsudoers/test6.out.ok
new file mode 100644
index 0000000..71eb49c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test6.out.ok
@@ -0,0 +1,12 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test6.sh b/plugins/sudoers/regress/testsudoers/test6.sh
new file mode 100755
index 0000000..f3b54f8
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test6.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Verify sudoers matching by uid.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+$TESTSUDOERS root id <<EOF
+#0 ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test7.out.ok b/plugins/sudoers/regress/testsudoers/test7.out.ok
new file mode 100644
index 0000000..71eb49c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test7.out.ok
@@ -0,0 +1,12 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test7.sh b/plugins/sudoers/regress/testsudoers/test7.sh
new file mode 100755
index 0000000..9e28c1a
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test7.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# Verify sudoers matching by gid.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+exec 2>&1
+$TESTSUDOERS root id <<EOF
+%#0 ALL = ALL
+EOF
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test8.out.ok b/plugins/sudoers/regress/testsudoers/test8.out.ok
new file mode 100644
index 0000000..51fa7cf
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test8.out.ok
@@ -0,0 +1,29 @@
+Testing @include without a newline
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
+
+Testing #include without a newline
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test8.sh b/plugins/sudoers/regress/testsudoers/test8.sh
new file mode 100755
index 0000000..c22b590
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test8.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# Test @include facility w/o a final newline.
+# Same as test2.sh but missing the final newline.
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+MYUID=`\ls -ln $TESTDIR/test2.inc | awk '{print $3}'`
+MYGID=`\ls -ln $TESTDIR/test2.inc | awk '{print $4}'`
+exec 2>&1
+
+echo "Testing @include without a newline"
+echo ""
+printf "@include $TESTDIR/test2.inc" | \
+ $TESTSUDOERS -U $MYUID -G $MYGID root id
+
+echo ""
+echo "Testing #include without a newline"
+echo ""
+printf "#include $TESTDIR/test2.inc" | \
+ $TESTSUDOERS -U $MYUID -G $MYGID root id
+
+exit 0
diff --git a/plugins/sudoers/regress/testsudoers/test9.out.ok b/plugins/sudoers/regress/testsudoers/test9.out.ok
new file mode 100644
index 0000000..71eb49c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test9.out.ok
@@ -0,0 +1,12 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host allowed
+ runas allowed
+ cmnd allowed
+
+Password required
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test9.sh b/plugins/sudoers/regress/testsudoers/test9.sh
new file mode 100755
index 0000000..850bbac
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test9.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Test #include facility
+#
+
+: ${TESTSUDOERS=testsudoers}
+
+MYUID=`\ls -ln $TESTDIR/test2.inc | awk '{print $3}'`
+MYGID=`\ls -ln $TESTDIR/test2.inc | awk '{print $4}'`
+exec 2>&1
+$TESTSUDOERS -U $MYUID -G $MYGID root id <<EOF
+#include $TESTDIR/test2.inc
+EOF
+
+exit 0