summaryrefslogtreecommitdiffstats
path: root/plugins/sudoers/regress/testsudoers
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/sudoers/regress/testsudoers')
-rw-r--r--plugins/sudoers/regress/testsudoers/group15
-rw-r--r--plugins/sudoers/regress/testsudoers/test1.out.ok8
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test1.sh15
-rw-r--r--plugins/sudoers/regress/testsudoers/test10.out.ok51
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test10.sh46
-rw-r--r--plugins/sudoers/regress/testsudoers/test11.out.ok21
-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.ok17
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test15.sh24
-rw-r--r--plugins/sudoers/regress/testsudoers/test16.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test16.sh41
-rw-r--r--plugins/sudoers/regress/testsudoers/test17.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test17.sh51
-rw-r--r--plugins/sudoers/regress/testsudoers/test18.out.ok60
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test18.sh40
-rw-r--r--plugins/sudoers/regress/testsudoers/test19.out.ok20
-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.ok25
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test2.sh25
-rw-r--r--plugins/sudoers/regress/testsudoers/test20.out.ok15
-rw-r--r--plugins/sudoers/regress/testsudoers/test20.sh18
-rw-r--r--plugins/sudoers/regress/testsudoers/test3.out.ok51
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test3.sh48
-rw-r--r--plugins/sudoers/regress/testsudoers/test4.out.ok5
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test4.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test5.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test5.sh31
-rw-r--r--plugins/sudoers/regress/testsudoers/test6.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test6.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test7.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test7.sh13
-rw-r--r--plugins/sudoers/regress/testsudoers/test8.out.ok25
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test8.sh24
-rw-r--r--plugins/sudoers/regress/testsudoers/test9.out.ok10
-rwxr-xr-xplugins/sudoers/regress/testsudoers/test9.sh15
42 files changed, 960 insertions, 0 deletions
diff --git a/plugins/sudoers/regress/testsudoers/group b/plugins/sudoers/regress/testsudoers/group
new file mode 100644
index 0000000..e2202d6
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/group
@@ -0,0 +1,15 @@
+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
+nogroup:*:32766:
+nobody:*:32767:
diff --git a/plugins/sudoers/regress/testsudoers/test1.out.ok b/plugins/sudoers/regress/testsudoers/test1.out.ok
new file mode 100644
index 0000000..5c292be
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test1.out.ok
@@ -0,0 +1,8 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+
+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..3515094
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test10.out.ok
@@ -0,0 +1,51 @@
+Testing @include of a path with escaped white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing @include of a double-quoted path with white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing #include of a path with escaped white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing #include of a double-quoted path with white space
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..f030dc8
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test11.out.ok
@@ -0,0 +1,21 @@
+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:
+
+Command unmatched
+
+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:
+
+Command unmatched
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..ca02857
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test15.out.ok
@@ -0,0 +1,17 @@
+Testing @include of a file with a missing newline
+
+Parses OK
+
+Entries for user root:
+
+ALL = /usr/bin/id
+ host matched
+ runas matched
+ cmnd unmatched
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..cdf3dc8
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test16.out.ok
@@ -0,0 +1,10 @@
+Parses OK
+
+Entries for user root:
+
+ALL = (ALL) ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..bb07d2c
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test17.out.ok
@@ -0,0 +1,10 @@
+Parses OK
+
+Entries for user root:
+
+ALL = (ALL) sha224:fIoq2MAfM/PZKTbkn9RE4VZ8YHjwnwTgE28Hxw== ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..b11d21a
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test18.out.ok
@@ -0,0 +1,60 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ^/bin/ls$ ^-[lAt]$
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = ^/bin/cat$ /var/log/*
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/cat ^/var/log/[^/]+$
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/*at ^/var/log/[^/]+$
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /usr/bin/grep \^foo$
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = sudoedit ^/etc/(motd|issue|hosts)$
+ host matched
+ runas matched
+ cmnd allowed
+
+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..a0de240
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test19.out.ok
@@ -0,0 +1,20 @@
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls ""
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+Parses OK
+
+Entries for user root:
+
+ALL = /bin/ls ""
+ host matched
+ runas matched
+ cmnd unmatched
+
+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..661f22e
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test2.out.ok
@@ -0,0 +1,25 @@
+Testing @include
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing #include
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..95f4c31
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test20.out.ok
@@ -0,0 +1,15 @@
+Parses OK
+
+Entries for user root:
+
+ALL = CHROOT=/ /bin/ls
+ host matched
+ runas matched
+ cmnd allowed
+
+ALL = CWD=/ /bin/pwd
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
diff --git a/plugins/sudoers/regress/testsudoers/test20.sh b/plugins/sudoers/regress/testsudoers/test20.sh
new file mode 100644
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/test3.out.ok b/plugins/sudoers/regress/testsudoers/test3.out.ok
new file mode 100644
index 0000000..788f2ea
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test3.out.ok
@@ -0,0 +1,51 @@
+Testing @includedir of an unquoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing @includedir of a double-quoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing #includedir of an unquoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing #includedir of a double-quoted path
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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/test4.out.ok b/plugins/sudoers/regress/testsudoers/test4.out.ok
new file mode 100644
index 0000000..cf68da5
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test4.out.ok
@@ -0,0 +1,5 @@
+testsudoers: test2.inc should be owned by uid 1
+
+Entries for user root:
+
+Command unmatched
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..a4ead0e
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test5.out.ok
@@ -0,0 +1,10 @@
+testsudoers: test5.inc is world writable
+
+Entries for user root:
+
+Command unmatched
+testsudoers: test5.inc should be owned by gid 4294967294
+
+Entries for user root:
+
+Command unmatched
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..3ec84bd
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test6.out.ok
@@ -0,0 +1,10 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..3ec84bd
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test7.out.ok
@@ -0,0 +1,10 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..b1ed931
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test8.out.ok
@@ -0,0 +1,25 @@
+Testing @include without a newline
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+Command allowed
+
+Testing #include without a newline
+
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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..3ec84bd
--- /dev/null
+++ b/plugins/sudoers/regress/testsudoers/test9.out.ok
@@ -0,0 +1,10 @@
+Parses OK
+
+Entries for user root:
+
+ALL = ALL
+ host matched
+ runas matched
+ cmnd allowed
+
+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