Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
Show First 20 Lines • Show All 2,293 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (*working_mode != ACE_WRITE_DATA) | if (*working_mode != ACE_WRITE_DATA) | ||||
return (SET_ERROR(EACCES)); | return (SET_ERROR(EACCES)); | ||||
return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode, | return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode, | ||||
check_privs, B_FALSE, cr)); | check_privs, B_FALSE, cr)); | ||||
} | } | ||||
/* | |||||
* Check if VEXEC is allowed. | |||||
* | |||||
* This routine is based on zfs_fastaccesschk_execute which has slowpath | |||||
* calling zfs_zaccess. This would be incorrect on FreeBSD (see | |||||
* zfs_freebsd_access for the difference). Thus this variant let's the | |||||
* caller handle the slowpath (if necessary). | |||||
* | |||||
* On top of that we perform a lockless check for ZFS_NO_EXECS_DENIED. | |||||
* | |||||
* Safe access to znode_t is provided by the vnode lock. | |||||
*/ | |||||
int | int | ||||
zfs_freebsd_fastaccesschk_execute(struct vnode *vp, cred_t *cr) | |||||
{ | |||||
boolean_t owner = B_FALSE; | |||||
boolean_t groupmbr = B_FALSE; | |||||
boolean_t is_attr; | |||||
uid_t uid = crgetuid(cr); | |||||
znode_t *zdp = VTOZ(vp); | |||||
if (zdp->z_pflags & ZFS_AV_QUARANTINED) | |||||
return (1); | |||||
is_attr = ((zdp->z_pflags & ZFS_XATTR) && | |||||
(ZTOV(zdp)->v_type == VDIR)); | |||||
if (is_attr) | |||||
return (1); | |||||
if (zdp->z_pflags & ZFS_NO_EXECS_DENIED) | |||||
return (0); | |||||
mutex_enter(&zdp->z_acl_lock); | |||||
if (FUID_INDEX(zdp->z_uid) != 0 || FUID_INDEX(zdp->z_gid) != 0) { | |||||
goto out_slow; | |||||
} | |||||
if (uid == zdp->z_uid) { | |||||
owner = B_TRUE; | |||||
if (zdp->z_mode & S_IXUSR) { | |||||
goto out; | |||||
} else { | |||||
goto out_slow; | |||||
} | |||||
} | |||||
if (groupmember(zdp->z_gid, cr)) { | |||||
groupmbr = B_TRUE; | |||||
if (zdp->z_mode & S_IXGRP) { | |||||
goto out; | |||||
} else { | |||||
goto out_slow; | |||||
} | |||||
} | |||||
if (!owner && !groupmbr) { | |||||
if (zdp->z_mode & S_IXOTH) { | |||||
goto out; | |||||
} | |||||
} | |||||
out: | |||||
mutex_exit(&zdp->z_acl_lock); | |||||
return (0); | |||||
out_slow: | |||||
mutex_exit(&zdp->z_acl_lock); | |||||
return (1); | |||||
} | |||||
#ifdef illumos | |||||
int | |||||
zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr) | zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr) | ||||
{ | { | ||||
boolean_t owner = B_FALSE; | boolean_t owner = B_FALSE; | ||||
boolean_t groupmbr = B_FALSE; | boolean_t groupmbr = B_FALSE; | ||||
boolean_t is_attr; | boolean_t is_attr; | ||||
uid_t uid = crgetuid(cr); | uid_t uid = crgetuid(cr); | ||||
int error; | int error; | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
slow: | slow: | ||||
DTRACE_PROBE(zfs__fastpath__execute__access__miss); | DTRACE_PROBE(zfs__fastpath__execute__access__miss); | ||||
ZFS_ENTER(zdp->z_zfsvfs); | ZFS_ENTER(zdp->z_zfsvfs); | ||||
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr); | error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr); | ||||
ZFS_EXIT(zdp->z_zfsvfs); | ZFS_EXIT(zdp->z_zfsvfs); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
/* | /* | ||||
* Determine whether Access should be granted/denied. | * Determine whether Access should be granted/denied. | ||||
* | * | ||||
* The least priv subsystem is always consulted as a basic privilege | * The least priv subsystem is always consulted as a basic privilege | ||||
* can define any form of access. | * can define any form of access. | ||||
*/ | */ | ||||
int | int | ||||
▲ Show 20 Lines • Show All 365 Lines • Show Last 20 Lines |