Cross-platform acltype
The acltype property is currently hidden on FreeBSD and does not reflect the NFSv4 style ZFS ACLs used on the platform. This makes it difficult to observe that a pool imported from FreeBSD on Linux has a different type of ACL that is being ignored, and vice versa. Add an nfsv4 acltype and expose the property on FreeBSD. Make the default acltype nfsv4 on FreeBSD. Setting acltype to an unhanded style is treated the same as setting it to off. The ACLs will not be removed, but they will be ignored. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ryan Moeller <ryan@iXsystems.com> Closes #10520
This commit is contained in:
parent
b302185a92
commit
485b50bb9e
|
@ -72,6 +72,7 @@ struct zfsvfs {
|
|||
boolean_t z_fuid_dirty; /* need to sync fuid table ? */
|
||||
struct zfs_fuid_info *z_fuid_replay; /* fuid info for replay */
|
||||
zilog_t *z_log; /* intent log pointer */
|
||||
uint_t z_acl_type; /* type of acl usable on this fs */
|
||||
uint_t z_acl_mode; /* acl chmod/mode behavior */
|
||||
uint_t z_acl_inherit; /* acl inheritance behavior */
|
||||
zfs_case_t z_case; /* case-sense */
|
||||
|
|
|
@ -68,6 +68,7 @@ extern "C" {
|
|||
*/
|
||||
#define ZFS_ACLTYPE_OFF 0
|
||||
#define ZFS_ACLTYPE_POSIX 1
|
||||
#define ZFS_ACLTYPE_NFSV4 2
|
||||
|
||||
/*
|
||||
* Field manipulation macros for the drr_versioninfo field of the
|
||||
|
|
|
@ -19,8 +19,12 @@
|
|||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
|
||||
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ACL_H
|
||||
|
@ -75,23 +79,24 @@ typedef struct acl_info acl_t;
|
|||
/*
|
||||
* The following are defined for ace_t.
|
||||
*/
|
||||
#define ACE_READ_DATA 0x00000001
|
||||
#define ACE_LIST_DIRECTORY 0x00000001
|
||||
#define ACE_WRITE_DATA 0x00000002
|
||||
#define ACE_ADD_FILE 0x00000002
|
||||
#define ACE_APPEND_DATA 0x00000004
|
||||
#define ACE_ADD_SUBDIRECTORY 0x00000004
|
||||
#define ACE_READ_NAMED_ATTRS 0x00000008
|
||||
#define ACE_WRITE_NAMED_ATTRS 0x00000010
|
||||
#define ACE_EXECUTE 0x00000020
|
||||
#define ACE_DELETE_CHILD 0x00000040
|
||||
#define ACE_READ_ATTRIBUTES 0x00000080
|
||||
#define ACE_WRITE_ATTRIBUTES 0x00000100
|
||||
#define ACE_DELETE 0x00010000
|
||||
#define ACE_READ_ACL 0x00020000
|
||||
#define ACE_WRITE_ACL 0x00040000
|
||||
#define ACE_WRITE_OWNER 0x00080000
|
||||
#define ACE_SYNCHRONIZE 0x00100000
|
||||
#define ACE_READ_DATA 0x00000001 /* file: read data */
|
||||
#define ACE_LIST_DIRECTORY 0x00000001 /* dir: list files */
|
||||
#define ACE_WRITE_DATA 0x00000002 /* file: write data */
|
||||
#define ACE_ADD_FILE 0x00000002 /* dir: create file */
|
||||
#define ACE_APPEND_DATA 0x00000004 /* file: append data */
|
||||
#define ACE_ADD_SUBDIRECTORY 0x00000004 /* dir: create subdir */
|
||||
#define ACE_READ_NAMED_ATTRS 0x00000008 /* FILE_READ_EA */
|
||||
#define ACE_WRITE_NAMED_ATTRS 0x00000010 /* FILE_WRITE_EA */
|
||||
#define ACE_EXECUTE 0x00000020 /* file: execute */
|
||||
#define ACE_TRAVERSE 0x00000020 /* dir: lookup name */
|
||||
#define ACE_DELETE_CHILD 0x00000040 /* dir: unlink child */
|
||||
#define ACE_READ_ATTRIBUTES 0x00000080 /* (all) stat, etc. */
|
||||
#define ACE_WRITE_ATTRIBUTES 0x00000100 /* (all) utimes, etc. */
|
||||
#define ACE_DELETE 0x00010000 /* (all) unlink self */
|
||||
#define ACE_READ_ACL 0x00020000 /* (all) getsecattr */
|
||||
#define ACE_WRITE_ACL 0x00040000 /* (all) setsecattr */
|
||||
#define ACE_WRITE_OWNER 0x00080000 /* (all) chown */
|
||||
#define ACE_SYNCHRONIZE 0x00100000 /* (all) */
|
||||
|
||||
#define ACE_FILE_INHERIT_ACE 0x0001
|
||||
#define ACE_DIRECTORY_INHERIT_ACE 0x0002
|
||||
|
@ -116,8 +121,6 @@ typedef struct acl_info acl_t;
|
|||
#define ACL_FLAGS_ALL (ACL_AUTO_INHERIT|ACL_PROTECTED| \
|
||||
ACL_DEFAULTED)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* These are only applicable in a CIFS context.
|
||||
*/
|
||||
|
@ -137,6 +140,8 @@ typedef struct acl_info acl_t;
|
|||
|
||||
#define ACE_ALL_TYPES 0x001F
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
typedef struct ace_object {
|
||||
uid_t a_who; /* uid or gid */
|
||||
uint32_t a_access_mask; /* read,write,... */
|
||||
|
@ -154,6 +159,21 @@ typedef struct ace_object {
|
|||
ACE_WRITE_ATTRIBUTES|ACE_DELETE|ACE_READ_ACL|ACE_WRITE_ACL| \
|
||||
ACE_WRITE_OWNER|ACE_SYNCHRONIZE)
|
||||
|
||||
#define ACE_ALL_WRITE_PERMS (ACE_WRITE_DATA|ACE_APPEND_DATA| \
|
||||
ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS|ACE_WRITE_ACL| \
|
||||
ACE_WRITE_OWNER|ACE_DELETE|ACE_DELETE_CHILD)
|
||||
|
||||
#define ACE_READ_PERMS (ACE_READ_DATA|ACE_READ_ACL|ACE_READ_ATTRIBUTES| \
|
||||
ACE_READ_NAMED_ATTRS)
|
||||
|
||||
#define ACE_WRITE_PERMS (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES| \
|
||||
ACE_WRITE_NAMED_ATTRS)
|
||||
|
||||
#define ACE_MODIFY_PERMS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
|
||||
ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_READ_NAMED_ATTRS| \
|
||||
ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \
|
||||
ACE_WRITE_ATTRIBUTES|ACE_DELETE|ACE_READ_ACL|ACE_SYNCHRONIZE)
|
||||
|
||||
/*
|
||||
* The following flags are supported by both NFSv4 ACLs and ace_t.
|
||||
*/
|
||||
|
@ -217,6 +237,7 @@ typedef struct ace_object {
|
|||
#define ACL_APPEND_ID 0x1 /* append uid/gid to user/group entries */
|
||||
#define ACL_COMPACT_FMT 0x2 /* build ACL in ls -V format */
|
||||
#define ACL_NORESOLVE 0x4 /* don't do name service lookups */
|
||||
#define ACL_SID_FMT 0x8 /* use usersid/groupsid when appropriate */
|
||||
|
||||
/*
|
||||
* Legacy aclcheck errors for aclent_t ACLs
|
||||
|
@ -272,13 +293,8 @@ extern int cmp2acls(void *, void *);
|
|||
|
||||
#endif /* !defined(_KERNEL) */
|
||||
|
||||
#if defined(__STDC__)
|
||||
extern int acl(const char *path, int cmd, int cnt, void *buf);
|
||||
extern int facl(int fd, int cmd, int cnt, void *buf);
|
||||
#else /* !__STDC__ */
|
||||
extern int acl();
|
||||
extern int facl();
|
||||
#endif /* defined(__STDC__) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -651,17 +651,28 @@ you must first remove all
|
|||
.Tn ACL
|
||||
entries which do not represent the current mode.
|
||||
.El
|
||||
.It Sy acltype Ns = Ns Sy off Ns | Ns Sy posix
|
||||
.It Sy acltype Ns = Ns Sy off Ns | Ns Sy nfsv4 Ns | Ns Sy posix
|
||||
Controls whether ACLs are enabled and if so what type of ACL to use.
|
||||
This property is not visible on FreeBSD yet.
|
||||
When this property is set to a type of ACL not supported by the current
|
||||
platform, the behavior is the same as if it were set to
|
||||
.Sy off .
|
||||
.Bl -tag -width "posixacl"
|
||||
.It Sy off
|
||||
default, when a file system has the
|
||||
default on Linux, when a file system has the
|
||||
.Sy acltype
|
||||
property set to off then ACLs are disabled.
|
||||
.It Sy noacl
|
||||
an alias for
|
||||
.Sy off
|
||||
.It Sy nfsv4
|
||||
default on FreeBSD, indicates that NFSv4-style ZFS ACLs should be used.
|
||||
These ACLs can be managed with the
|
||||
.Xr getfacl 1
|
||||
and
|
||||
.Xr setfacl 1
|
||||
commands on FreeBSD. The
|
||||
.Sy nfsv4
|
||||
ZFS ACL type is not yet supported on Linux.
|
||||
.It Sy posix
|
||||
indicates POSIX ACLs should be used. POSIX ACLs are specific to Linux and are
|
||||
not functional on other platforms. POSIX ACLs are stored as an extended
|
||||
|
|
|
@ -2494,7 +2494,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
|||
|
||||
/*
|
||||
* Translate traditional unix VREAD/VWRITE/VEXEC mode into
|
||||
* native ACL format and call zfs_zaccess()
|
||||
* NFSv4-style ZFS ACL format and call zfs_zaccess()
|
||||
*/
|
||||
int
|
||||
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
|
||||
|
|
|
@ -592,6 +592,14 @@ acl_inherit_changed_cb(void *arg, uint64_t newval)
|
|||
zfsvfs->z_acl_inherit = newval;
|
||||
}
|
||||
|
||||
static void
|
||||
acl_type_changed_cb(void *arg, uint64_t newval)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = arg;
|
||||
|
||||
zfsvfs->z_acl_type = newval;
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_register_callbacks(vfs_t *vfsp)
|
||||
{
|
||||
|
@ -722,6 +730,8 @@ zfs_register_callbacks(vfs_t *vfsp)
|
|||
zfs_prop_to_name(ZFS_PROP_EXEC), exec_changed_cb, zfsvfs);
|
||||
error = error ? error : dsl_prop_register(ds,
|
||||
zfs_prop_to_name(ZFS_PROP_SNAPDIR), snapdir_changed_cb, zfsvfs);
|
||||
error = error ? error : dsl_prop_register(ds,
|
||||
zfs_prop_to_name(ZFS_PROP_ACLTYPE), acl_type_changed_cb, zfsvfs);
|
||||
error = error ? error : dsl_prop_register(ds,
|
||||
zfs_prop_to_name(ZFS_PROP_ACLMODE), acl_mode_changed_cb, zfsvfs);
|
||||
error = error ? error : dsl_prop_register(ds,
|
||||
|
@ -797,6 +807,11 @@ zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os)
|
|||
return (error);
|
||||
zfsvfs->z_case = (uint_t)val;
|
||||
|
||||
error = zfs_get_zplprop(os, ZFS_PROP_ACLTYPE, &val);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
zfsvfs->z_acl_type = (uint_t)val;
|
||||
|
||||
/*
|
||||
* Fold case on file systems that are always or sometimes case
|
||||
* insensitive.
|
||||
|
@ -1232,6 +1247,10 @@ zfs_domount(vfs_t *vfsp, char *osname)
|
|||
"xattr", &pval, NULL)))
|
||||
goto out;
|
||||
xattr_changed_cb(zfsvfs, pval);
|
||||
if ((error = dsl_prop_get_integer(osname,
|
||||
"acltype", &pval, NULL)))
|
||||
goto out;
|
||||
acl_type_changed_cb(zfsvfs, pval);
|
||||
zfsvfs->z_issnap = B_TRUE;
|
||||
zfsvfs->z_os->os_sync = ZFS_SYNC_DISABLED;
|
||||
|
||||
|
@ -2220,6 +2239,9 @@ zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
|
|||
case ZFS_PROP_CASE:
|
||||
*value = ZFS_CASE_SENSITIVE;
|
||||
break;
|
||||
case ZFS_PROP_ACLTYPE:
|
||||
*value = ZFS_ACLTYPE_NFSV4;
|
||||
break;
|
||||
default:
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -4744,6 +4744,8 @@ static int
|
|||
zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
|
||||
caller_context_t *ct)
|
||||
{
|
||||
znode_t *zp;
|
||||
zfsvfs_t *zfsvfs;
|
||||
|
||||
switch (cmd) {
|
||||
case _PC_LINK_MAX:
|
||||
|
@ -4757,11 +4759,25 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
|
|||
*valp = (int)SPA_MINBLOCKSIZE;
|
||||
return (0);
|
||||
case _PC_ACL_EXTENDED:
|
||||
#if 0 /* POSIX ACLs are not implemented for ZFS on FreeBSD yet. */
|
||||
zp = VTOZ(vp);
|
||||
zfsvfs = zp->z_zfsvfs;
|
||||
ZFS_ENTER(zfsvfs);
|
||||
ZFS_VERIFY_ZP(zp);
|
||||
*valp = zfsvfs->z_acl_type == ZFSACLTYPE_POSIX ? 1 : 0;
|
||||
ZFS_EXIT(zfsvfs);
|
||||
#else
|
||||
*valp = 0;
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
case _PC_ACL_NFS4:
|
||||
*valp = 1;
|
||||
zp = VTOZ(vp);
|
||||
zfsvfs = zp->z_zfsvfs;
|
||||
ZFS_ENTER(zfsvfs);
|
||||
ZFS_VERIFY_ZP(zp);
|
||||
*valp = zfsvfs->z_acl_type == ZFS_ACLTYPE_NFSV4 ? 1 : 0;
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (0);
|
||||
|
||||
case _PC_ACL_PATH_MAX:
|
||||
|
|
|
@ -2666,7 +2666,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
|||
|
||||
/*
|
||||
* Translate traditional unix S_IRUSR/S_IWUSR/S_IXUSR mode into
|
||||
* native ACL format and call zfs_zaccess()
|
||||
* NFSv4-style ZFS ACL format and call zfs_zaccess()
|
||||
*/
|
||||
int
|
||||
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
|
||||
|
|
|
@ -352,6 +352,7 @@ acltype_changed_cb(void *arg, uint64_t newval)
|
|||
zfsvfs_t *zfsvfs = arg;
|
||||
|
||||
switch (newval) {
|
||||
case ZFS_ACLTYPE_NFSV4:
|
||||
case ZFS_ACLTYPE_OFF:
|
||||
zfsvfs->z_acl_type = ZFS_ACLTYPE_OFF;
|
||||
zfsvfs->z_sb->s_flags &= ~SB_POSIXACL;
|
||||
|
|
|
@ -254,6 +254,7 @@ zfs_prop_init(void)
|
|||
static zprop_index_t acltype_table[] = {
|
||||
{ "off", ZFS_ACLTYPE_OFF },
|
||||
{ "posix", ZFS_ACLTYPE_POSIX },
|
||||
{ "nfsv4", ZFS_ACLTYPE_NFSV4 },
|
||||
{ "disabled", ZFS_ACLTYPE_OFF }, /* bkwrd compatibility */
|
||||
{ "noacl", ZFS_ACLTYPE_OFF }, /* bkwrd compatibility */
|
||||
{ "posixacl", ZFS_ACLTYPE_POSIX }, /* bkwrd compatibility */
|
||||
|
@ -428,11 +429,15 @@ zfs_prop_init(void)
|
|||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
||||
"discard | groupmask | passthrough | restricted", "ACLMODE",
|
||||
acl_mode_table);
|
||||
#ifndef __FreeBSD__
|
||||
zprop_register_index(ZFS_PROP_ACLTYPE, "acltype", ZFS_ACLTYPE_OFF,
|
||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
|
||||
"off | posix", "ACLTYPE", acltype_table);
|
||||
zprop_register_index(ZFS_PROP_ACLTYPE, "acltype",
|
||||
#ifdef __linux__
|
||||
/* Linux doesn't natively support ZFS's NFSv4-style ACLs. */
|
||||
ZFS_ACLTYPE_OFF,
|
||||
#else
|
||||
ZFS_ACLTYPE_NFSV4,
|
||||
#endif
|
||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
|
||||
"off | nfsv4 | posix", "ACLTYPE", acltype_table);
|
||||
zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
|
||||
ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
||||
"discard | noallow | restricted | passthrough | passthrough-x",
|
||||
|
@ -702,12 +707,6 @@ zfs_prop_init(void)
|
|||
* that we don't have to change the values of the zfs_prop_t enum, or
|
||||
* have NULL pointers in the zfs_prop_table[].
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
zprop_register_impl(ZFS_PROP_ACLTYPE, "acltype", PROP_TYPE_INDEX,
|
||||
ZFS_ACLTYPE_OFF, NULL, PROP_INHERIT,
|
||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
|
||||
"off | posix", "ACLTYPE", B_FALSE, B_FALSE, acltype_table);
|
||||
#endif
|
||||
zprop_register_hidden(ZFS_PROP_REMAPTXG, "remaptxg", PROP_TYPE_NUMBER,
|
||||
PROP_READONLY, ZFS_TYPE_DATASET, "REMAPTXG");
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ if is_linux; then
|
|||
|
||||
# these are an alternate set of property values
|
||||
PROP_ALTVALS="\
|
||||
off off \
|
||||
nfsv4 off \
|
||||
fletcher4 lzjb off \
|
||||
off /tmp/zfstest 100M off \
|
||||
512 10m off \
|
||||
|
@ -74,7 +74,7 @@ elif is_freebsd; then
|
|||
|
||||
# these are an alternate set of property values
|
||||
PROP_ALTVALS="\
|
||||
off off \
|
||||
nfsv4 off \
|
||||
fletcher4 lzjb off \
|
||||
off /tmp/zfstest 100M off \
|
||||
512 10m off \
|
||||
|
|
|
@ -73,7 +73,7 @@ props=(
|
|||
mountpoint none compression lz4
|
||||
compression on compression off
|
||||
compression lzjb acltype off
|
||||
acltype posix xattr sa
|
||||
acltype posix acltype nfsv4
|
||||
atime on atime off
|
||||
devices on devices off
|
||||
exec on exec off
|
||||
|
@ -84,11 +84,11 @@ props=(
|
|||
aclinherit discard aclinherit noallow
|
||||
aclinherit secure aclinherit passthrough
|
||||
canmount off canmount on
|
||||
xattr on xattr off
|
||||
compression gzip compression gzip-$((RANDOM%9 + 1))
|
||||
compression zstd compression zstd-$((RANDOM%9 + 1))
|
||||
compression zstd-fast copies $((RANDOM%3 + 1))
|
||||
compression zstd-fast-$((RANDOM%9 + 1))
|
||||
compression zstd-fast-$((RANDOM%9 + 1)) xattr sa
|
||||
xattr on xattr off
|
||||
)
|
||||
elif is_freebsd; then
|
||||
# property value property value
|
||||
|
@ -115,7 +115,8 @@ props=(
|
|||
compression gzip compression gzip-$((RANDOM%9 + 1))
|
||||
compression zstd compression zstd-$((RANDOM%9 + 1))
|
||||
compression zstd-fast copies $((RANDOM%3 + 1))
|
||||
compression zstd-fast-$((RANDOM%9 + 1))
|
||||
compression zstd-fast-$((RANDOM%9 + 1)) acltype off
|
||||
acltype posix acltype nfsv4
|
||||
)
|
||||
else
|
||||
# property value property value
|
||||
|
|
|
@ -116,7 +116,7 @@ for fs in "$POOL" "$POOL/pclone" "$POOL/$FS" "$POOL/$FS/fs1" \
|
|||
"$POOL/$FS/fs1/fs2" "$POOL/$FS/fs1/fclone" ; do
|
||||
rand_set_prop $fs aclinherit "discard" "noallow" "secure" "passthrough"
|
||||
rand_set_prop $fs checksum "on" "off" "fletcher2" "fletcher4" "sha256"
|
||||
rand_set_prop $fs acltype "off" "posix" "noacl" "posixacl"
|
||||
rand_set_prop $fs acltype "off" "posix" "nfsv4" "noacl" "posixacl"
|
||||
rand_set_prop $fs atime "on" "off"
|
||||
rand_set_prop $fs checksum "on" "off" "fletcher2" "fletcher4" "sha256"
|
||||
rand_set_prop $fs compression "${compress_prop_vals[@]}"
|
||||
|
|
Loading…
Reference in New Issue