diff --git a/tools/regression/fstest/Makefile b/tools/regression/fstest/Makefile index ae982b66ed87..13c62e97f7d8 100644 --- a/tools/regression/fstest/Makefile +++ b/tools/regression/fstest/Makefile @@ -4,7 +4,7 @@ OSTYPE=$(shell uname) ifeq "${OSTYPE}" "FreeBSD" CFLAGS += -D__OS_FreeBSD__ -CFLAGS += -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_LCHFLAGS +CFLAGS += -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_LCHFLAGS -DHAS_FREEBSD_ACL endif ifeq "${OSTYPE}" "SunOS" diff --git a/tools/regression/fstest/fstest.c b/tools/regression/fstest/fstest.c index 798c70222c4f..e058e0a20d30 100644 --- a/tools/regression/fstest/fstest.c +++ b/tools/regression/fstest/fstest.c @@ -45,6 +45,9 @@ #define stat64 stat #define lstat64 lstat #endif +#ifdef HAS_FREEBSD_ACL +#include +#endif #ifndef ALLPERMS #define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) @@ -75,7 +78,12 @@ enum action { ACTION_TRUNCATE, ACTION_STAT, ACTION_LSTAT, - ACTION_PATHCONF + ACTION_PATHCONF, +#ifdef HAS_FREEBSD_ACL + ACTION_PREPENDACL, + ACTION_READACL, +#endif + ACTION_WRITE, }; #define TYPE_NONE 0x0000 @@ -118,6 +126,11 @@ static struct syscall_desc syscalls[] = { { "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, { "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, { "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, +#ifdef HAS_FREEBSD_ACL + { "prependacl", ACTION_PREPENDACL, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, + { "readacl", ACTION_READACL, { TYPE_STRING, TYPE_NONE } }, +#endif + { "write", ACTION_WRITE, { TYPE_STRING, TYPE_NONE } }, { NULL, -1, { TYPE_NONE } } }; @@ -397,6 +410,11 @@ call_syscall(struct syscall_desc *scall, char *argv[]) char *str; long long num; } args[MAX_ARGS]; +#ifdef HAS_FREEBSD_ACL + int entry_id = ACL_FIRST_ENTRY; + acl_t acl, newacl; + acl_entry_t entry, newentry; +#endif /* * Verify correctness of the arguments. @@ -540,6 +558,48 @@ call_syscall(struct syscall_desc *scall, char *argv[]) rval = -1; break; } +#ifdef HAS_FREEBSD_ACL + case ACTION_PREPENDACL: + rval = -1; + + acl = acl_get_file(STR(0), ACL_TYPE_NFS4); + if (acl == NULL) + break; + + newacl = acl_from_text(STR(1)); + if (acl == NULL) + break; + + while (acl_get_entry(newacl, entry_id, &newentry) == 1) { + entry_id = ACL_NEXT_ENTRY; + + if (acl_create_entry_np(&acl, &entry, 0)) + break; + + if (acl_copy_entry(entry, newentry)) + break; + } + + rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl); + break; + + case ACTION_READACL: + acl = acl_get_file(STR(0), ACL_TYPE_NFS4); + if (acl == NULL) + rval = -1; + else + rval = 0; + break; +#endif + + case ACTION_WRITE: + rval = open(STR(0), O_WRONLY); + if (rval < 0) + break; + + rval = write(rval, "x", 1); + break; + default: fprintf(stderr, "unsupported syscall\n"); exit(1); diff --git a/tools/regression/fstest/tests/chmod/12.t b/tools/regression/fstest/tests/chmod/12.t new file mode 100644 index 000000000000..db8c9b8184b5 --- /dev/null +++ b/tools/regression/fstest/tests/chmod/12.t @@ -0,0 +1,32 @@ +#!/bin/sh +# $FreeBSD$ + +desc="verify SUID/SGID bit behaviour" + +dir=`dirname $0` +. ${dir}/../misc.sh + +echo "1..10" + +n0=`namegen` +n1=`namegen` +n2=`namegen` + +expect 0 mkdir ${n2} 0755 +cdir=`pwd` +cd ${n2} + +# Check whether writing to the file by non-owner clears the SUID. +expect 0 create ${n0} 04777 +expect 0 -u 65534 -g 65534 write ${n0} +expect 0777 stat ${n0} mode +expect 0 unlink ${n0} + +# Check whether writing to the file by non-owner clears the SGID. +expect 0 create ${n0} 02777 +expect 0 -u 65534 -g 65534 write ${n0} +expect 0777 stat ${n0} mode +expect 0 unlink ${n0} + +cd ${cdir} +expect 0 rmdir ${n2} diff --git a/tools/regression/fstest/tests/granular/00.t b/tools/regression/fstest/tests/granular/00.t new file mode 100644 index 000000000000..84533bd0b444 --- /dev/null +++ b/tools/regression/fstest/tests/granular/00.t @@ -0,0 +1,110 @@ +#!/bin/sh +# $FreeBSD$ + +desc="NFSv4 granular permissions checking - WRITE_DATA vs APPEND_DATA on directories" + +dir=`dirname $0` +. ${dir}/../misc.sh + +echo "1..49" + +n0=`namegen` +n1=`namegen` +n2=`namegen` +n3=`namegen` + +expect 0 mkdir ${n2} 0755 +expect 0 mkdir ${n3} 0777 +cdir=`pwd` +cd ${n2} + +# Tests 2..7 - check out whether root user can do stuff. +# Can create files? +expect 0 create ${n0} 0644 + +# Can create symlinks? +expect 0 link ${n0} ${n1} +expect 0 unlink ${n1} +expect 0 unlink ${n0} + +# Can create directories? +expect 0 mkdir ${n0} 0755 +expect 0 rmdir ${n0} + +# Check whether user 65534 is permitted to create and remove +# files, but not subdirectories. +expect 0 prependacl . user:65534:write_data::allow,user:65534:append_data::deny + +# Can create files? +expect 0 -u 65534 -g 65534 create ${n0} 0644 + +# Can create symlinks? +expect 0 -u 65534 -g 65534 link ${n0} ${n1} +expect 0 -u 65534 -g 65534 unlink ${n1} +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Can create directories? +expect EACCES -u 65534 -g 65534 mkdir ${n0} 0755 +expect ENOENT -u 65534 -g 65534 rmdir ${n0} +expect 0 mkdir ${n0} 0755 +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# Can move files from other directory? +expect 0 create ../${n3}/${n1} 0644 +expect 0 -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} + +# Can move files from other directory overwriting existing files? +expect 0 create ../${n3}/${n1} 0644 +expect 0 -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} + +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Can move directories from other directory? +expect 0 mkdir ../${n3}/${n1} 0777 +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} + +# Can move directories from other directory overwriting existing directory? +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} +expect 0 -u 65534 -g 65534 rmdir ../${n3}/${n1} + +# Check whether user 65534 is permitted to create +# subdirectories, but not files - and to remove neither of them. +expect 0 prependacl . user:65534:write_data::deny,user:65534:append_data::allow + +# Can create files? +expect EACCES -u 65534 -g 65534 create ${n0} 0644 + +# Can create symlinks? +expect 0 create ${n0} 0644 +expect EACCES -u 65534 -g 65534 link ${n0} ${n1} +expect ENOENT -u 65534 -g 65534 unlink ${n1} +expect EACCES -u 65534 -g 65534 unlink ${n0} +expect 0 unlink ${n0} + +# Can create directories? +expect 0 -u 65534 -g 65534 mkdir ${n0} 0755 +expect EACCES -u 65534 -g 65534 rmdir ${n0} +expect 0 rmdir ${n0} + +# Can move files from other directory? +expect 0 create ../${n3}/${n1} 0644 +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} + +# Can move files from other directory overwriting existing files? +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} +expect 0 -u 65534 -g 65534 unlink ../${n3}/${n1} + +# Can move directories from other directory? +expect 0 mkdir ../${n3}/${n1} 0777 +expect 0 -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} + +# Can move directories from other directory overwriting existing directory? +expect 0 mkdir ../${n3}/${n1} 0777 +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} +expect 0 prependacl . user:65534:delete_child::allow +expect 0 -u 65534 -g 65534 rename ../${n3}/${n1} ${n0} +expect 0 -u 65534 -g 65534 rmdir ${n0} + +cd ${cdir} +expect 0 rmdir ${n2} +expect 0 rmdir ${n3} diff --git a/tools/regression/fstest/tests/granular/01.t b/tools/regression/fstest/tests/granular/01.t new file mode 100644 index 000000000000..f1bac1b0214f --- /dev/null +++ b/tools/regression/fstest/tests/granular/01.t @@ -0,0 +1,35 @@ +#!/bin/sh +# $FreeBSD$ + +desc="NFSv4 granular permissions checking - ACL_READ_ATTRIBUTES and ACL_WRITE_ATTRIBUTES" + +dir=`dirname $0` +. ${dir}/../misc.sh + +echo "1..12" + +n0=`namegen` +n1=`namegen` +n2=`namegen` + +expect 0 mkdir ${n2} 0755 +cdir=`pwd` +cd ${n2} + +# Tests 1..12 - check out whether user 65534 is permitted to read attributes. +expect 0 create ${n0} 0644 +expect 0 lstat ${n0} size +expect 0 -u 65534 -g 65534 stat ${n0} size +expect 0 prependacl ${n0} user:65534:read_attributes::deny +expect 0 lstat ${n0} size +expect EACCES -u 65534 -g 65534 stat ${n0} size +expect 0 prependacl ${n0} user:65534:read_attributes::allow +expect 0 -u 65534 -g 65534 stat ${n0} size +expect 0 lstat ${n0} size +expect 0 unlink ${n0} + +# Tests 12..12 - check out whether user 65534 is permitted to write attributes. +# XXX: Check if ACL_WRITE_ATTRIBUTES allows for modifying access times. + +cd ${cdir} +expect 0 rmdir ${n2} diff --git a/tools/regression/fstest/tests/granular/02.t b/tools/regression/fstest/tests/granular/02.t new file mode 100644 index 000000000000..80d66547c79b --- /dev/null +++ b/tools/regression/fstest/tests/granular/02.t @@ -0,0 +1,142 @@ +#!/bin/sh +# $FreeBSD$ + +desc="NFSv4 granular permissions checking - ACL_READ_ACL and ACL_WRITE_ACL" + +dir=`dirname $0` +. ${dir}/../misc.sh + +echo "1..83" + +n0=`namegen` +n1=`namegen` +n2=`namegen` + +expect 0 mkdir ${n2} 0755 +cdir=`pwd` +cd ${n2} + +# Check whether user 65534 is permitted to read ACL. +expect 0 create ${n0} 0644 +expect 0 readacl ${n0} +expect 0 -u 65534 -g 65534 readacl ${n0} +expect 0 prependacl ${n0} user:65534:read_acl::deny +expect 0 readacl ${n0} +expect EACCES -u 65534 -g 65534 readacl ${n0} +expect 0 prependacl ${n0} user:65534:read_acl::allow +expect 0 -u 65534 -g 65534 readacl ${n0} +expect 0 readacl ${n0} +expect 0 unlink ${n0} + +# Check whether user 65534 is permitted to write ACL. +expect 0 create ${n0} 0644 +expect EPERM -u 65534 -g 65534 prependacl ${n0} user:65534:read_data::allow +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:read_data::allow +expect 0 unlink ${n0} + +# Check whether user 65534 is permitted to write mode. +expect 0 create ${n0} 0755 +expect EPERM -u 65534 -g 65534 chmod ${n0} 0777 +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect 0 -u 65534 -g 65534 chmod ${n0} 0777 +expect 0 unlink ${n0} + +# There is an interesting problem with interaction between ACL_WRITE_ACL +# and SUID/SGID bits. In case user does have ACL_WRITE_ACL, but is not +# a file owner, Solaris does the following: +# 1. Setting SUID fails with EPERM. +# 2. Setting SGID succeeds, but mode is not changed. +# 3. Modifying ACL does not clear SUID nor SGID bits. +# 4. Writing the file does clear both SUID and SGID bits. +# +# What we are doing is the following: +# 1. Setting SUID or SGID fails with EPERM. +# 2. Modifying ACL does not clear SUID nor SGID bits. +# 3. Writing the file does clear both SUID and SGID bits. +# +# Check whether user 65534 is denied to write mode with SUID bit. +expect 0 create ${n0} 0755 +expect EPERM -u 65534 -g 65534 chmod ${n0} 04777 +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect EPERM -u 65534 -g 65534 chmod ${n0} 04777 +expect 0 unlink ${n0} + +# Check whether user 65534 is denied to write mode with SGID bit. +expect 0 create ${n0} 0755 +expect EPERM -u 65534 -g 65534 chmod ${n0} 02777 +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect EPERM -u 65534 -g 65534 chmod ${n0} 02777 +expect 0 unlink ${n0} + +# Check whether user 65534 is allowed to write mode with sticky bit. +expect 0 mkdir ${n0} 0755 +expect EPERM -u 65534 -g 65534 chmod ${n0} 01777 +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect 0 -u 65534 -g 65534 chmod ${n0} 01777 +expect 0 rmdir ${n0} + +# Check whether modifying the ACL by not-owner preserves the SUID. +expect 0 create ${n0} 04755 +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:write_data::allow +expect 04755 stat ${n0} mode +expect 0 unlink ${n0} + +# Check whether modifying the ACL by not-owner preserves the SGID. +expect 0 create ${n0} 02755 +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:write_data::allow +expect 02755 stat ${n0} mode +expect 0 unlink ${n0} + +# Check whether modifying the ACL by not-owner preserves the sticky bit. +expect 0 mkdir ${n0} 0755 +expect 0 chmod ${n0} 01755 +expect 0 prependacl ${n0} user:65534:write_acl::allow +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:write_data::allow +expect 01755 stat ${n0} mode +expect 0 rmdir ${n0} + +# Clearing the SUID and SGID bits when being written to by non-owner +# is checked in chmod/12.t. + +# Check whether the file owner is always permitted to get and set +# ACL and file mode, even if ACL_{READ,WRITE}_ACL would deny it. +expect 0 chmod . 0777 +expect 0 -u 65534 -g 65534 create ${n0} 0600 +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:write_acl::deny +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:read_acl::deny +expect 0 -u 65534 -g 65534 readacl ${n0} +expect 0600 -u 65534 -g 65534 stat ${n0} mode +expect 0 -u 65534 -g 65534 chmod ${n0} 0777 +expect 0 unlink ${n0} + +expect 0 -u 65534 -g 65534 mkdir ${n0} 0600 +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:write_acl::deny +expect 0 -u 65534 -g 65534 prependacl ${n0} user:65534:read_acl::deny +expect 0 -u 65534 -g 65534 readacl ${n0} +expect 0600 -u 65534 -g 65534 stat ${n0} mode +expect 0 -u 65534 -g 65534 chmod ${n0} 0777 +expect 0 rmdir ${n0} + +# Check whether the root is allowed for these as well. +expect 0 -u 65534 -g 65534 create ${n0} 0600 +expect 0 prependacl ${n0} everyone@:write_acl::deny +expect 0 prependacl ${n0} everyone@:read_acl::deny +expect 0 readacl ${n0} +expect 0600 stat ${n0} mode +expect 0 chmod ${n0} 0777 +expect 0 unlink ${n0} + +expect 0 -u 65534 -g 65534 mkdir ${n0} 0600 +expect 0 prependacl ${n0} everyone@:write_acl::deny +expect 0 prependacl ${n0} everyone@:read_acl::deny +expect 0600 stat ${n0} mode +expect 0 readacl ${n0} +expect 0600 stat ${n0} mode +expect 0 chmod ${n0} 0777 +expect 0 rmdir ${n0} + +cd ${cdir} +expect 0 rmdir ${n2} diff --git a/tools/regression/fstest/tests/granular/03.t b/tools/regression/fstest/tests/granular/03.t new file mode 100644 index 000000000000..ec8cebfaa2d0 --- /dev/null +++ b/tools/regression/fstest/tests/granular/03.t @@ -0,0 +1,132 @@ +#!/bin/sh +# $FreeBSD$ + +desc="NFSv4 granular permissions checking - DELETE and DELETE_CHILD" + +dir=`dirname $0` +. ${dir}/../misc.sh + +echo "1..65" + +n0=`namegen` +n1=`namegen` +n2=`namegen` +n3=`namegen` + +expect 0 mkdir ${n2} 0755 +expect 0 mkdir ${n3} 0777 +cdir=`pwd` +cd ${n2} + +# Unlink allowed on writable directory. +expect 0 create ${n0} 0644 +expect EACCES -u 65534 -g 65534 unlink ${n0} +expect 0 prependacl . user:65534:write_data::allow +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Moving file elsewhere allowed on writable directory. +expect 0 create ${n0} 0644 +expect 0 prependacl . user:65534:write_data::deny +expect EACCES -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} +expect 0 prependacl . user:65534:write_data::allow +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} + +# Moving file from elsewhere allowed on writable directory. +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Moving file from elsewhere overwriting local file allowed +# on writable directory. +expect 0 create ${n0} 0644 +expect 0 create ../${n3}/${n0} 0644 +expect 0 prependacl . user:65534:write_data::deny +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 prependacl . user:65534:write_data::allow +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Denied DELETE changes nothing wrt removing. +expect 0 create ${n0} 0644 +expect 0 prependacl ${n0} user:65534:delete::deny +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Denied DELETE changes nothing wrt moving elsewhere or from elsewhere. +expect 0 create ${n0} 0644 +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 unlink ${n0} + +# DELETE_CHILD denies unlink on writable directory. +expect 0 create ${n0} 0644 +expect 0 prependacl . user:65534:delete_child::deny +expect EPERM -u 65534 -g 65534 unlink ${n0} +expect 0 unlink ${n0} + +# DELETE_CHILD denies moving file elsewhere. +expect 0 create ${n0} 0644 +expect EPERM -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} +expect 0 rename ${n0} ../${n3}/${n0} + +# DELETE_CHILD does not deny moving file from elsewhere +# to a writable directory. +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# DELETE_CHILD denies moving file from elsewhere +# to a writable directory overwriting local file. +expect 0 create ../${n3}/${n0} 0644 +expect EPERM -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# DELETE allowed on file allows for unlinking, no matter +# what permissions on containing directory are. +expect 0 prependacl ${n0} user:65534:delete::allow +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Same for moving the file elsewhere. +expect 0 create ${n0} 0644 +expect 0 prependacl ${n0} user:65534:delete::allow +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} + +# Same for moving the file from elsewhere into a writable +# directory with DELETE_CHILD denied. +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 unlink ${n0} + +# DELETE does not allow for overwriting a file in a unwritable +# directory with DELETE_CHILD denied. +expect 0 create ${n0} 0644 +expect 0 create ../${n3}/${n0} 0644 +expect 0 prependacl . user:65534:write_data::deny +expect 0 prependacl . user:65534:delete_child::deny +expect EPERM -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 prependacl ${n0} user:65534:delete::allow +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# But it allows for plain deletion. +expect 0 -u 65534 -g 65534 unlink ${n0} + +# DELETE_CHILD allowed on unwritable directory. +expect 0 create ${n0} 0644 +expect 0 prependacl . user:65534:delete_child::allow +expect 0 -u 65534 -g 65534 unlink ${n0} + +# Moving things elsewhere is allowed. +expect 0 create ${n0} 0644 +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} + +# Moving things back is not. +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# Even if we're overwriting. +expect 0 create ${n0} 0644 +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# Even if we have DELETE on the existing file. +expect 0 prependacl ${n0} user:65534:delete::allow +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# Denied DELETE changes nothing wrt removing. +expect 0 prependacl ${n0} user:65534:delete::deny +expect 0 -u 65534 -g 65534 unlink ${n0} + +cd ${cdir} +expect 0 rmdir ${n2} diff --git a/tools/regression/fstest/tests/granular/04.t b/tools/regression/fstest/tests/granular/04.t new file mode 100644 index 000000000000..9bd55f25023a --- /dev/null +++ b/tools/regression/fstest/tests/granular/04.t @@ -0,0 +1,78 @@ +#!/bin/sh +# $FreeBSD$ + +desc="NFSv4 granular permissions checking - ACL_WRITE_OWNER" + +dir=`dirname $0` +. ${dir}/../misc.sh + +echo "1..52" + +n0=`namegen` +n1=`namegen` +n2=`namegen` + +expect 0 mkdir ${n2} 0755 +cdir=`pwd` +cd ${n2} + +# ACL_WRITE_OWNER permits to set gid to our own only. +expect 0 create ${n0} 0644 +expect 0,0 lstat ${n0} uid,gid +expect EPERM -u 65534 -g 65532,65531 chown ${n0} -1 65532 +expect 0,0 lstat ${n0} uid,gid +expect 0 prependacl ${n0} user:65534:write_owner::allow +expect EPERM -u 65534 -g 65532,65531 chown ${n0} -1 65530 +expect 0,0 lstat ${n0} uid,gid +expect 0 -u 65534 -g 65532,65531 chown ${n0} -1 65532 +expect 0,65532 lstat ${n0} uid,gid +expect 0 unlink ${n0} + +# ACL_WRITE_OWNER permits to set uid to our own only. +expect 0 create ${n0} 0644 +expect 0,0 lstat ${n0} uid,gid +expect EPERM -u 65534 -g 65532,65531 chown ${n0} 65534 65531 +expect 0,0 lstat ${n0} uid,gid +expect 0 prependacl ${n0} user:65534:write_owner::allow +expect EPERM -u 65534 -g 65532,65531 chown ${n0} 65530 65531 +expect 0,0 lstat ${n0} uid,gid +expect 0 -u 65534 -g 65532,65531 chown ${n0} 65534 65531 +expect 65534,65531 lstat ${n0} uid,gid +expect 0 unlink ${n0} + +# When non-owner calls chown(2) successfully, set-uid and set-gid bits are +# removed, except when both uid and gid are equal to -1. +expect 0 create ${n0} 0644 +expect 0 prependacl ${n0} user:65534:write_owner::allow +expect 0 chmod ${n0} 06555 +expect 06555 lstat ${n0} mode +expect 0 -u 65534 -g 65533,65532 chown ${n0} 65534 65532 +expect 0555,65534,65532 lstat ${n0} mode,uid,gid +expect 0 chmod ${n0} 06555 +expect 06555 lstat ${n0} mode +expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 65533 +expect 0555,65534,65533 lstat ${n0} mode,uid,gid +expect 0 chmod ${n0} 06555 +expect 06555 lstat ${n0} mode +expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 -1 +expect 06555,65534,65533 lstat ${n0} mode,uid,gid +expect 0 unlink ${n0} + +expect 0 mkdir ${n0} 0755 +expect 0 prependacl ${n0} user:65534:write_owner::allow +expect 0 chmod ${n0} 06555 +expect 06555 lstat ${n0} mode +expect 0 -u 65534 -g 65533,65532 chown ${n0} 65534 65532 +expect 0555,65534,65532 lstat ${n0} mode,uid,gid +expect 0 chmod ${n0} 06555 +expect 06555 lstat ${n0} mode +expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 65533 +expect 0555,65534,65533 lstat ${n0} mode,uid,gid +expect 0 chmod ${n0} 06555 +expect 06555 lstat ${n0} mode +expect 0 -u 65534 -g 65533,65532 chown ${n0} -1 -1 +expect 06555,65534,65533 lstat ${n0} mode,uid,gid +expect 0 rmdir ${n0} + +cd ${cdir} +expect 0 rmdir ${n2} diff --git a/tools/regression/fstest/tests/granular/05.t b/tools/regression/fstest/tests/granular/05.t new file mode 100644 index 000000000000..7b29774ee021 --- /dev/null +++ b/tools/regression/fstest/tests/granular/05.t @@ -0,0 +1,147 @@ +#!/bin/sh +# $FreeBSD$ + +desc="NFSv4 granular permissions checking - DELETE and DELETE_CHILD with directories" + +dir=`dirname $0` +. ${dir}/../misc.sh + +echo "1..68" + +n0=`namegen` +n1=`namegen` +n2=`namegen` +n3=`namegen` + +expect 0 mkdir ${n2} 0755 +expect 0 mkdir ${n3} 0777 +cdir=`pwd` +cd ${n2} + +# Unlink allowed on writable directory. +expect 0 mkdir ${n0} 0755 +expect EACCES -u 65534 -g 65534 rmdir ${n0} +expect 0 prependacl . user:65534:write_data::allow +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# Moving directory elsewhere allowed on writable directory. +expect 0 mkdir ${n0} 0777 +expect 0 prependacl . user:65534:write_data::deny +expect EACCES -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} +expect 0 prependacl . user:65534:write_data::allow +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} + +# 12 +# Moving directory from elsewhere allowed on writable directory. +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 prependacl . user:65534:append_data::allow +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# Moving directory from elsewhere overwriting local directory allowed +# on writable directory. +expect 0 mkdir ${n0} 0755 +expect 0 mkdir ../${n3}/${n0} 0777 +expect 0 prependacl . user:65534:write_data::deny +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 prependacl . user:65534:write_data::allow +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# 23 +# Denied DELETE changes nothing wrt removing. +expect 0 mkdir ${n0} 0755 +expect 0 prependacl ${n0} user:65534:delete::deny +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# Denied DELETE changes nothing wrt moving elsewhere or from elsewhere. +expect 0 mkdir ${n0} 0777 +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# DELETE_CHILD denies unlink on writable directory. +expect 0 mkdir ${n0} 0755 +expect 0 prependacl . user:65534:delete_child::deny +expect EPERM -u 65534 -g 65534 rmdir ${n0} +expect 0 rmdir ${n0} + +# 35 +# DELETE_CHILD denies moving directory elsewhere. +expect 0 mkdir ${n0} 0777 +expect EPERM -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} +expect 0 rename ${n0} ../${n3}/${n0} + +# DELETE_CHILD does not deny moving directory from elsewhere +# to a writable directory. +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# DELETE_CHILD denies moving directory from elsewhere +# to a writable directory overwriting local directory. +expect 0 mkdir ../${n3}/${n0} 0755 +expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# DELETE allowed on directory allows for unlinking, no matter +# what permissions on containing directory are. +expect 0 prependacl ${n0} user:65534:delete::allow +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# Same for moving the directory elsewhere. +expect 0 mkdir ${n0} 0777 +expect 0 prependacl ${n0} user:65534:delete::allow +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} + +# 46 +# Same for moving the directory from elsewhere into a writable +# directory with DELETE_CHILD denied. +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 rmdir ${n0} + +# DELETE does not allow for overwriting a directory in a unwritable +# directory with DELETE_CHILD denied. +expect 0 mkdir ${n0} 0755 +expect 0 mkdir ../${n3}/${n0} 0777 +expect 0 prependacl . user:65534:write_data::deny +expect 0 prependacl . user:65534:delete_child::deny +expect EPERM -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 prependacl ${n0} user:65534:delete::allow +# XXX: expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# 54 +# But it allows for plain deletion. +# XXX: expect 0 -u 65534 -g 65534 rmdir ${n0} +expect 0 rmdir ${n0} + +# DELETE_CHILD allowed on unwritable directory. +expect 0 mkdir ${n0} 0755 +expect 0 prependacl . user:65534:delete_child::allow +expect 0 -u 65534 -g 65534 rmdir ${n0} + +# Moving things elsewhere is allowed. +expect 0 mkdir ${n0} 0777 +expect 0 -u 65534 -g 65534 rename ${n0} ../${n3}/${n0} + +# 60 +# Moving things back is not. +# XXX: expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# Even if we're overwriting. +# XXX: expect 0 mkdir ${n0} 0755 +expect 0 mkdir ../${n3}/${n0} 0777 +# XXX: expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 mkdir ../${n3}/${n0} 0777 + +# Even if we have DELETE on the existing directory. +expect 0 prependacl ${n0} user:65534:delete::allow +# XXX: expect EACCES -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} +expect 0 -u 65534 -g 65534 rename ../${n3}/${n0} ${n0} + +# Denied DELETE changes nothing wrt removing. +expect 0 prependacl ${n0} user:65534:delete::deny +expect 0 -u 65534 -g 65534 rmdir ${n0} + +cd ${cdir} +expect 0 rmdir ${n2}