#!/bin/sh # Show all commands when run with environment variable VERBOSE=yes. test -z $VERBOSE || set -x test $USE_ACL = 0 && do { echo "Skipping test: insufficient ACL support" exit 77 } # func_tmpdir # creates a temporary directory. # Sets variable # - tmp pathname of freshly created temporary directory proc func_tmpdir { # Use the environment variable TMPDIR, falling back to /tmp. This allows # users to specify a different temporary directory, for example, if their # /tmp is filled up or too small. : $(TMPDIR=/tmp) do { # Use the mktemp program if available. If not available, hide the error # message. setglobal tmp = $[shell {umask 077 && mktemp -d "$TMPDIR/glXXXXXX"}] && test -n $tmp && test -d $tmp } || do { # Use a simple mkdir command. It is guaranteed to fail if the directory # already exists. $RANDOM is bash specific and expands to empty in shells # other than bash, ksh and zsh. Its use does not increase security; # rather, it minimizes the probability of failure in a very cluttered /tmp # directory. setglobal tmp = "$TMPDIR/gl$Pid-$RANDOM" shell {umask 077 && mkdir $tmp} } || do { echo "$0: cannot create a temporary directory in $TMPDIR" > !2 exit 1 } } func_tmpdir setglobal builddir = $[pwd] cd $builddir || do { echo "$0: cannot determine build directory (unreadable parent dir?)" > !2 exit 1 } # Switch to a temporary directory, to increase the likelihood that ACLs are # supported on the current file system. (/tmp is usually locally mounted, # whereas the build dir is sometimes NFS-mounted.) shell { cd $tmp # Prepare tmpfile0. rm -f tmpfile[0-9] tmp.err echo "Simple contents" > tmpfile0 chmod 600 tmpfile0 # Classification of the platform according to the programs available for # manipulating ACLs. # Possible values are: # linux, cygwin, freebsd, solaris, hpux, hpuxjfs, osf1, aix, macosx, irix, none. # TODO: Support also native Windows platforms (mingw). setglobal acl_flavor = 'none' if shell {getfacl tmpfile0 >/dev/null} 2>/dev/null { # Platforms with the getfacl and setfacl programs. # Linux, FreeBSD, Solaris, Cygwin. if shell {setfacl --help >/dev/null} 2>/dev/null { # Linux, Cygwin. if shell {env LC_ALL=C setfacl --help | grep ' --set-file' >/dev/null} 2>/dev/null { # Linux. setglobal acl_flavor = 'linux' } else { setglobal acl_flavor = 'cygwin' } } else { # FreeBSD, Solaris. if shell {env LC_ALL=C setfacl !2 > !1 | grep '\-x entries' >/dev/null} 2>/dev/null { # FreeBSD. setglobal acl_flavor = 'freebsd' } else { # Solaris. setglobal acl_flavor = 'solaris' } } } else { if shell {lsacl / >/dev/null} 2>/dev/null { # Platforms with the lsacl and chacl programs. # HP-UX, sometimes also IRIX. if shell {getacl tmpfile0 >/dev/null} 2>/dev/null { # HP-UX 11.11 or newer. setglobal acl_flavor = 'hpuxjfs' } else { # HP-UX 11.00. setglobal acl_flavor = 'hpux' } } else { if shell {getacl tmpfile0 >/dev/null} 2>/dev/null { # Tru64, NonStop Kernel. if shell {getacl -m tmpfile0 >/dev/null} 2>/dev/null { # Tru64. setglobal acl_flavor = 'osf1' } else { # NonStop Kernel. setglobal acl_flavor = 'nsk' } } else { if shell {aclget tmpfile0 >/dev/null} 2>/dev/null { # AIX. setglobal acl_flavor = 'aix' } else { if shell {fsaclctl -v >/dev/null} 2>/dev/null { # Mac OS X. setglobal acl_flavor = 'macosx' } else { if test -f /sbin/chacl { # IRIX. setglobal acl_flavor = 'irix' } } } } } } # func_test_file_has_acl file expected # tests the result of the file_has_acl function on file, and checks that it # matches the expected value. proc func_test_file_has_acl { setglobal res = $["$builddir"/test-file-has-acl$(EXEEXT) $1] test $res = $2 || do { echo "file_has_acl(\"$1\") returned $res, expected $2" !1 > !2 exit 1 } } # func_test_has_acl file expected # tests the result of the file_has_acl function on file, and checks that it # matches the expected value, also taking into account the system's 'ls' # program. match $acl_flavor { with freebsd | solaris | hpux | macosx match $acl_flavor { with freebsd | solaris | hpux setglobal acl_ls_option = '"-ld'" with macosx setglobal acl_ls_option = '"-lde'" } proc func_test_has_acl { func_test_file_has_acl $1 $2 match $[/bin/ls $acl_ls_option $1 | sed 1q] { with ??????????+* test $2 = yes || do { echo "/bin/ls $acl_ls_option $1 shows an ACL, but expected $2" !1 > !2 exit 1 } with ??????????" "* test $2 = no || do { echo "/bin/ls $acl_ls_option $1 shows no ACL, but expected $2" !1 > !2 exit 1 } } } with irix proc func_test_has_acl { func_test_file_has_acl $1 $2 match $[/bin/ls -ldD $1 | sed 1q] { with *" []" test $2 = no || do { echo "/bin/ls -ldD $1 shows no ACL, but expected $2" !1 > !2 exit 1 } with * test $2 = yes || do { echo "/bin/ls -ldD $1 shows an ACL, but expected $2" !1 > !2 exit 1 } } } with * proc func_test_has_acl { func_test_file_has_acl $1 $2 } } func_test_has_acl tmpfile0 no mkdir tmpdir0 func_test_has_acl tmpdir0 no if test $acl_flavor != none { # A POSIX compliant 'id' program. if test -f /usr/xpg4/bin/id { setglobal ID = '/usr/xpg4/bin/id' } else { setglobal ID = 'id' } # Use a user and group id different from the current one, to avoid # redundant/ambiguous ACLs. setglobal myuid = $[$ID -u] setglobal mygid = $[$ID -g] setglobal auid = '1' if test $auid = $myuid { setglobal auid = '2'; } setglobal agid = '1' if test $agid = $mygid { setglobal agid = '2'; } match $acl_flavor { with linux | freebsd | solaris # Set an ACL for a user. if setfacl -m user:$auid:1 tmpfile0 { func_test_has_acl tmpfile0 yes # Remove the ACL for the user. match $acl_flavor { with linux setfacl -x user:$auid tmpfile0 with freebsd setfacl -x user:$auid:1 tmpfile0 with * setfacl -d user:$auid:1 tmpfile0 } # On Linux and FreeBSD, the ACL for the mask is implicitly added. # On Solaris, it is always there. match $acl_flavor { with linux | freebsd func_test_has_acl tmpfile0 yes with * func_test_has_acl tmpfile0 no } # Remove the ACL for the mask, if it was implicitly added. match $acl_flavor { with linux | freebsd setfacl -x mask: tmpfile0 with * setfacl -d mask: tmpfile0 } func_test_has_acl tmpfile0 no } with cygwin # Set an ACL for a group. if setfacl -m group:0:1 tmpfile0 { func_test_has_acl tmpfile0 yes # Remove the ACL for the group. setfacl -d group:0 tmpfile0 func_test_has_acl tmpfile0 no } with hpux | hpuxjfs # Set an ACL for a user. setglobal orig = $[lsacl tmpfile0 | sed -e 's/ tmpfile0$//] if chacl -r "$(orig)($auid.%,--x)" tmpfile0 { func_test_has_acl tmpfile0 yes # Remove the ACL for the user. chacl -d "($auid.%,--x)" tmpfile0 func_test_has_acl tmpfile0 no } else { if test $acl_flavor = hpuxjfs { # Set an ACL for a user. setacl -m user:$auid:1 tmpfile0 func_test_has_acl tmpfile0 yes # Remove the ACL for the user. setacl -d user:$auid tmpfile0 func_test_has_acl tmpfile0 no } } with osf1 # Set an ACL for a user. setacl -u user:$auid:1 tmpfile0 !2 > tmp.err cat tmp.err !1 > !2 if grep 'Error:' tmp.err > /dev/null \ || grep 'Operation not supported' tmp.err > /dev/null { : } else { func_test_has_acl tmpfile0 yes # Remove the ACL for the user. setacl -x user:$auid:1 tmpfile0 func_test_has_acl tmpfile0 no } with nsk # Set an ACL for a user. setacl -m user:$auid:1 tmpfile0 func_test_has_acl tmpfile0 yes # Remove the ACL for the user. setacl -d user:$auid tmpfile0 func_test_has_acl tmpfile0 no with aix # Set an ACL for a user. do { aclget tmpfile0 | sed -e 's/disabled$/enabled/'; echo " permit --x u:$auid"; } | aclput tmpfile0 if aclget tmpfile0 | grep enabled > /dev/null { func_test_has_acl tmpfile0 yes # Remove the ACL for the user. aclget tmpfile0 | grep -v ' u:[^ ]*$' | aclput tmpfile0 func_test_has_acl tmpfile0 no } with macosx # Set an ACL for a user. /bin/chmod +a "user:daemon allow execute" tmpfile0 func_test_has_acl tmpfile0 yes # Remove the ACL for the user. /bin/chmod -a "user:daemon allow execute" tmpfile0 func_test_has_acl tmpfile0 no with irix # Set an ACL for a user. /sbin/chacl user::rw-,group::---,other::---,user:$auid:--x tmpfile0 !2 > tmp.err cat tmp.err !1 > !2 if test -s tmp.err { :; } else { func_test_has_acl tmpfile0 yes # Remove the ACL for the user. /sbin/chacl user::rw-,group::---,other::--- tmpfile0 func_test_has_acl tmpfile0 no } } } rm -f tmpfile[0-9] tmp.err rm -rf tmpdir0 } || exit 1 rm -rf $tmp exit 0