Overview

This is a test suite for NFSv4 acls.  Each C program tests a single
operation by calling the corresponding system call, possibly preceded by an
open, and looking at the return code.

There is also a set of shell scripts to drive the tests.  For each test, the
corresponding acl rights bit is turned off, then the test is run to see
whether the operation succeeds.  If the acls are working, the operation
should fail.

A better test would be to look at the file system on the server to see
whether the operation has succeeded, rather than trusting the return code
from the system call on the client.  We do not (yet) do this.

The set of tests should be run several times for user, group, and other
aces, for all security types, and for cross-realm authentication.

We do not test the "x" bit on files, which is enforced only on the client.

==

Operation

You will need a recent version of nfs4_setfacl that supports the "-s" option.

We recommend you mount with the "noac" option.  This shouldn't make any
difference to the tests, but will reduce confusion if you want to look at an
acl to see what's going on.

runtests [-d testdir] [-p aclprinc] [-u user]

The user (principal) that starts the test run will own the test files.  You
can change the principal used on the acl with the "-p" flag, and the
effective user for the operations with the "-u" flag.  These will normally
map to the same identity, although it's also useful to do testing with OWNER
and EVERYONE acls.

First run a simple single-user auth_sys test:

mount -t nfs4 -o noac snoopy:/ /snoopy
./runtests -d /snoopy/home/alice

This will create the directory "/snoopy/home/alice/sandbox" for testing.  In
this directory, the test will create a test subdirectory and a test file,
set the acl on the test subject, and run access tests.

Next run the tests single-user with sec=krb5 (and variants).  

mount -t nfs4 -o noac,sec=krb5 snoopy:/ /snoopy
runtests -u alice -p :alice@citi.umich.edu -d /snoopy/home/alice

Then try with cross-user:

su bob
runtests -u alice -p :alice@citi.umich.edu -d /snoopy/home/bob

And user vs EVERYONE:

su bob
runtests -u alice -p :EVERYONE@ -d /snoopy/home/bob

Group tests are also possible:

runtests -u alice -p g:GROUP@ -d /snoopy/home/bob
runtests -u alice -p g:sys@citi.umich.edu -d /snoopy/home/bob

Next try some cross-realm tests.  We assume you are already set up for
cross-realm kerberos authentication and v4 file access.  If not, see the
"NFS Version 4 Open Source Reference Implementation" document at
http://www.citi.umich.edu/projects/nfsv4/linux/ .

We provide a template for entering test users into your ldap database.  You
will need to edit this to put in the names of your kerberos realm and nfs
domain.  Then this file can be used as input to the ldapadd command:

ldapadd -Y GSSAPI -h ldapserver -f testuser.ldif

A cross-realm test will look something like this:

kinit alice@foreign.domain
su bob
runtests -u alice -p :alice@foreign.domain -d /snoopy/home/bob

==

Results

If you see "*** FAIL ***" that means some operation succeeded when it should
have been disallowed by the acl.  "PASS" means the operation failed as
expected.  "errno X" means the operation failed, but did not return the
expected error code.  It would be prudent to investigate these.

The setacl test may fail for single-user tests.  This is because most
servers allow the owner of a file to set the acl regardless of the "C" bit,
and is not usually considered a problem.  If the setacl test fails
cross-user, you do have a problem!

Servers often modify the acl sent by the client to reduce the set of rights
to something that the server understands and can enforce.  This will
sometimes result in an acl being set that looks nothing like the one the
client sent.  The resulting acl should be a subset of the rights from the
original.

==

Examples

fstab:
snoopy:/ /snoopy nfs4 rw,noac,noauto,intr 0 0
manhattan:/vol/citi1 /manhattan nfs4 rw,noac,intr 0 0

./runtests -d /snoopy/home/rees
./runtests -d /manhattan/nobody

==

Sample runs

auth_sys single user

runtests -d /snoopy/home/rees
testdir = /snoopy/home/rees/sandbox
nfs4_setfacl -s A::OWNER@:rwaxdnNtTcCoy file
test write A::OWNER@:raxdnNtTcCoy file file
  nfs4_setfacl -s A::OWNER@:raxdnNtTcCoy file
  PASS
test read A::OWNER@:waxdnNtTcCoy file file
  nfs4_setfacl -s A::OWNER@:waxdnNtTcCoy file
  PASS
test append A::OWNER@:rwxdnNtTcCoy file file
  nfs4_setfacl -s A::OWNER@:rwxdnNtTcCoy file
  PASS
test chown A::OWNER@:rwaxdnNtTcCy file file
  nfs4_setfacl -s A::OWNER@:rwaxdnNtTcCy file
  PASS
test setacl A::OWNER@:rwaxdnNtTcoy file file
  nfs4_setfacl -s A::OWNER@:rwaxdnNtTcoy file
  *** FAIL ***
test creat A::OWNER@:xlsDnNtTcCoy dir dir/file
  nfs4_setfacl -s A::OWNER@:xlsDnNtTcCoy dir
  PASS
test listdir A::OWNER@:xsfDnNtTcCoy dir dir
  nfs4_setfacl -s A::OWNER@:xsfDnNtTcCoy dir
  PASS
test mkdir A::OWNER@:xlfDnNtTcCoy dir dir/dir
  nfs4_setfacl -s A::OWNER@:xlfDnNtTcCoy dir
  PASS
test lookup A::OWNER@:lfsDnNtTcCoy dir dir/file
  nfs4_setfacl -s A::OWNER@:lfsDnNtTcCoy dir
  PASS
test rm A::OWNER@:xlfsnNtTcCoy dir dir/file
  nfs4_setfacl -s A::OWNER@:xlfsnNtTcCoy dir
  PASS

auth_krb single user

% ./runtests -p :rees@citi.umich.edu -d /snoopy/home/rees
testdir = /snoopy/home/rees/sandbox
nfs4_setfacl -s A::rees@citi.umich.edu:rwaxdnNtTcCoy file
test write A::rees@citi.umich.edu:raxdnNtTcCoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:raxdnNtTcCoy file
  PASS
test read A::rees@citi.umich.edu:waxdnNtTcCoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:waxdnNtTcCoy file
  PASS
test append A::rees@citi.umich.edu:rwxdnNtTcCoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:rwxdnNtTcCoy file
  PASS
test chown A::rees@citi.umich.edu:rwaxdnNtTcCy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:rwaxdnNtTcCy file
  PASS
test setacl A::rees@citi.umich.edu:rwaxdnNtTcoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:rwaxdnNtTcoy file
  *** FAIL ***
test creat A::rees@citi.umich.edu:xlsDnNtTcCoy dir dir/file
  nfs4_setfacl -s A::rees@citi.umich.edu:xlsDnNtTcCoy dir
  PASS
test listdir A::rees@citi.umich.edu:xsfDnNtTcCoy dir dir
  nfs4_setfacl -s A::rees@citi.umich.edu:xsfDnNtTcCoy dir
  PASS
test mkdir A::rees@citi.umich.edu:xlfDnNtTcCoy dir dir/dir
  nfs4_setfacl -s A::rees@citi.umich.edu:xlfDnNtTcCoy dir
  PASS
test lookup A::rees@citi.umich.edu:lfsDnNtTcCoy dir dir/file
  nfs4_setfacl -s A::rees@citi.umich.edu:lfsDnNtTcCoy dir
  PASS
test rm A::rees@citi.umich.edu:xlfsnNtTcCoy dir dir/file
  nfs4_setfacl -s A::rees@citi.umich.edu:xlfsnNtTcCoy dir
  PASS

auth_krb cross-user

# ./runtests -u rees -p :rees@citi.umich.edu -d /snoopy/home/rees/root
testdir = /snoopy/home/rees/root/sandbox
nfs4_setfacl -s A::rees@citi.umich.edu:rwaxdnNtTcCoy file
test write A::rees@citi.umich.edu:raxdnNtTcCoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:raxdnNtTcCoy file
  PASS
test read A::rees@citi.umich.edu:waxdnNtTcCoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:waxdnNtTcCoy file
  PASS
test append A::rees@citi.umich.edu:rwxdnNtTcCoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:rwxdnNtTcCoy file
  PASS
test chown A::rees@citi.umich.edu:rwaxdnNtTcCy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:rwaxdnNtTcCy file
  PASS
test setacl A::rees@citi.umich.edu:rwaxdnNtTcoy file file
  nfs4_setfacl -s A::rees@citi.umich.edu:rwaxdnNtTcoy file
  errno 1
test creat A::rees@citi.umich.edu:xlsDnNtTcCoy dir dir/file
  nfs4_setfacl -s A::rees@citi.umich.edu:xlsDnNtTcCoy dir
  PASS
test listdir A::rees@citi.umich.edu:xsfDnNtTcCoy dir dir
  nfs4_setfacl -s A::rees@citi.umich.edu:xsfDnNtTcCoy dir
  PASS
test mkdir A::rees@citi.umich.edu:xlfDnNtTcCoy dir dir/dir
  nfs4_setfacl -s A::rees@citi.umich.edu:xlfDnNtTcCoy dir
  PASS
test lookup A::rees@citi.umich.edu:lfsDnNtTcCoy dir dir/file
  nfs4_setfacl -s A::rees@citi.umich.edu:lfsDnNtTcCoy dir
  PASS
test rm A::rees@citi.umich.edu:xlfsnNtTcCoy dir dir/file
  nfs4_setfacl -s A::rees@citi.umich.edu:xlfsnNtTcCoy dir
  PASS

==

Acl definitions:

        r - NFS4_ACE_READ_DATA
        w - NFS4_ACE_WRITE_DATA
        a - NFS4_ACE_APPEND_DATA
        x - NFS4_ACE_EXECUTE
        d - NFS4_ACE_DELETE
        l - NFS4_ACE_LIST_DIRECTORY
        f - NFS4_ACE_ADD_FILE
        s - NFS4_ACE_ADD_SUBDIRECTORY
        n - NFS4_ACE_READ_NAMED_ATTRS
        N - NFS4_ACE_WRITE_NAMED_ATTRS
        D - NFS4_ACE_DELETE_CHILD
        t - NFS4_ACE_READ_ATTRIBUTES
        T - NFS4_ACE_WRITE_ATTRIBUTES
        c - NFS4_ACE_READ_ACL
        C - NFS4_ACE_WRITE_ACL
        o - NFS4_ACE_WRITE_OWNER
        y - NFS4_ACE_SYNCHRONIZE

   READ_DATA              Permission to read the data of the file
   LIST_DIRECTORY         Permission to list the contents of a
                          directory
   WRITE_DATA             Permission to modify the file's data
   ADD_FILE               Permission to add a new file to a
                          directory
   APPEND_DATA            Permission to append data to a file
   ADD_SUBDIRECTORY       Permission to create a subdirectory to a
                          directory
   READ_NAMED_ATTRS       Permission to read the named attributes
                          of a file
   WRITE_NAMED_ATTRS      Permission to write the named attributes
                          of a file
   EXECUTE                Permission to execute a file
   DELETE_CHILD           Permission to delete a file or directory
                          within a directory
   READ_ATTRIBUTES        The ability to read basic attributes
                          (non-acls) of a file
   WRITE_ATTRIBUTES       Permission to change basic attributes
   DELETE                 Permission to Delete the file
   READ_ACL               Permission to Read the ACL
   WRITE_ACL              Permission to Write the ACL
   WRITE_OWNER            Permission to change the owner

   "OWNER"                The owner of the file.
   "GROUP"                The group associated with the file.
   "EVERYONE"             The world.
   "INTERACTIVE"          Accessed from an interactive terminal.
   "NETWORK"              Accessed via the network.
   "DIALUP"               Accessed as a dialup user to the server.
   "BATCH"                Accessed from a batch job.
   "ANONYMOUS"            Accessed without any authentication.
   "AUTHENTICATED"        Any authenticated user (opposite of
                          ANONYMOUS)
   "SERVICE"              Access from a system service.
