diff options
author | rwatson <rwatson@FreeBSD.org> | 2002-10-15 21:28:24 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2002-10-15 21:28:24 +0000 |
commit | 174c4a00340b84a2df9e0f1df28291d7ef2fd517 (patch) | |
tree | 187af12acf6000c21e79a98cb4f5733500a219b3 /sys | |
parent | 9d886b383adb272dacbd3ad798f632462c1cbd4f (diff) | |
download | FreeBSD-src-174c4a00340b84a2df9e0f1df28291d7ef2fd517.zip FreeBSD-src-174c4a00340b84a2df9e0f1df28291d7ef2fd517.tar.gz |
Push most UFS ACL behavior behind a check for MNT_ACLS, permitting ACLs
to be administratively disabled as needed on UFS/UFS2 file systems. This
also has the effect of preventing the slightly more expensive ACL code
from running on non-ACL file systems, avoiding storage allocation for
ACLs that may be read from disk. MNT_ACLS may be set at mount-time
using mount -o acls, or implicitly by setting the FS_ACLS flag using
tunefs. On UFS1, you may also have to configure ACL store.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
Diffstat (limited to 'sys')
-rw-r--r-- | sys/ufs/ufs/ufs_acl.c | 12 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 218 |
2 files changed, 129 insertions, 101 deletions
diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c index 390e0db..cb2eb85 100644 --- a/sys/ufs/ufs/ufs_acl.c +++ b/sys/ufs/ufs/ufs_acl.c @@ -225,6 +225,12 @@ ufs_getacl(ap) struct inode *ip = VTOI(ap->a_vp); int error, len; + /* + * XXX: If ufs_getacl() should work on file systems not supporting + * ACLs, remove this check. + */ + if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) + return (EOPNOTSUPP); /* * Attempt to retrieve the ACL based on the ACL type. @@ -362,6 +368,9 @@ ufs_setacl(ap) mode_t old_mode, preserve_mask; int error; + if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) + return (EOPNOTSUPP); + /* * If this is a set operation rather than a delete operation, * invoke VOP_ACLCHECK() on the passed ACL to determine if it is @@ -475,6 +484,9 @@ ufs_aclcheck(ap) } */ *ap; { + if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) + return (EOPNOTSUPP); + /* * Verify we understand this type of ACL, and that it applies * to this kind of object. diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 8e9715d..29fd55f 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -367,33 +367,37 @@ ufs_access(ap) return (EPERM); #ifdef UFS_ACL - MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); - len = sizeof(*acl); - error = VOP_GETACL(vp, ACL_TYPE_ACCESS, acl, ap->a_cred, ap->a_td); - switch (error) { - case EOPNOTSUPP: - error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, - ap->a_mode, ap->a_cred, NULL); - break; - case 0: - error = vaccess_acl_posix1e(vp->v_type, ip->i_uid, ip->i_gid, - acl, ap->a_mode, ap->a_cred, NULL); - break; - default: - printf("ufs_access(): Error retrieving ACL on object (%d).\n", - error); - /* - * XXX: Fall back until debugged. Should eventually - * possibly log an error, and return EPERM for safety. - */ + if ((vp->v_mount->mnt_flag & MNT_ACLS) != 0) { + MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); + len = sizeof(*acl); + error = VOP_GETACL(vp, ACL_TYPE_ACCESS, acl, ap->a_cred, + ap->a_td); + switch (error) { + case EOPNOTSUPP: + error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, + ip->i_gid, ap->a_mode, ap->a_cred, NULL); + break; + case 0: + error = vaccess_acl_posix1e(vp->v_type, ip->i_uid, + ip->i_gid, acl, ap->a_mode, ap->a_cred, NULL); + break; + default: + printf( +"ufs_access(): Error retrieving ACL on object (%d).\n", + error); + /* + * XXX: Fall back until debugged. Should + * eventually possibly log an error, and return + * EPERM for safety. + */ + error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, + ip->i_gid, ap->a_mode, ap->a_cred, NULL); + } + FREE(acl, M_ACL); + } else +#endif /* !UFS_ACL */ error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, ap->a_mode, ap->a_cred, NULL); - } - FREE(acl, M_ACL); -#else - error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, - ap->a_mode, ap->a_cred, NULL); -#endif return (error); } @@ -1436,58 +1440,63 @@ ufs_mkdir(ap) #endif /* !SUIDDIR */ ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; #ifdef UFS_ACL - MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); - MALLOC(dacl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); + acl = dacl = NULL; + if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) { + MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); + MALLOC(dacl, struct acl *, sizeof(*dacl), M_ACL, M_WAITOK); - /* - * Retrieve default ACL from parent, if any. - */ - error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, - cnp->cn_thread); - switch (error) { - case 0: /* - * Retrieved a default ACL, so merge mode and ACL if - * necessary. + * Retrieve default ACL from parent, if any. */ - if (acl->acl_cnt != 0) { + error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, + cnp->cn_thread); + switch (error) { + case 0: + /* + * Retrieved a default ACL, so merge mode and ACL if + * necessary. + */ + if (acl->acl_cnt != 0) { + /* + * Two possible ways for default ACL to not + * be present. First, the EA can be + * undefined, or second, the default ACL can + * be blank. If it's blank, fall through to + * the it's not defined case. + */ + ip->i_mode = dmode; + DIP(ip, i_mode) = dmode; + *dacl = *acl; + ufs_sync_acl_from_inode(ip, acl); + break; + } + /* FALLTHROUGH */ + + case EOPNOTSUPP: /* - * Two possible ways for default ACL to not be - * present. First, the EA can be undefined, - * or second, the default ACL can be blank. - * If it's blank, fall through to the it's - * not defined case. + * Just use the mode as-is. */ ip->i_mode = dmode; DIP(ip, i_mode) = dmode; - *dacl = *acl; - ufs_sync_acl_from_inode(ip, acl); + FREE(acl, M_ACL); + FREE(dacl, M_ACL); + dacl = acl = NULL; break; + + default: + UFS_VFREE(tvp, ip->i_number, dmode); + vput(tvp); + FREE(acl, M_ACL); + FREE(dacl, M_ACL); + return (error); } - /* FALLTHROUGH */ - - case EOPNOTSUPP: - /* - * Just use the mode as-is. - */ + } else { +#endif /* !UFS_ACL */ ip->i_mode = dmode; DIP(ip, i_mode) = dmode; - FREE(acl, M_ACL); - FREE(dacl, M_ACL); - dacl = acl = NULL; - break; - - default: - UFS_VFREE(tvp, ip->i_number, dmode); - vput(tvp); - FREE(acl, M_ACL); - FREE(dacl, M_ACL); - return (error); +#ifdef UFS_ACL } -#else /* !UFS_ACL */ - ip->i_mode = dmode; - DIP(ip, i_mode) = dmode; -#endif /* !UFS_ACL */ +#endif tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ ip->i_effnlink = 2; ip->i_nlink = 2; @@ -2342,53 +2351,60 @@ ufs_makeinode(mode, dvp, vpp, cnp) #endif /* !SUIDDIR */ ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; #ifdef UFS_ACL - MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); - /* - * Retrieve default ACL for parent, if any. - */ - error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, - cnp->cn_thread); - switch (error) { - case 0: + acl = NULL; + if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) { + MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); + /* - * Retrieved a default ACL, so merge mode and ACL if - * necessary. + * Retrieve default ACL for parent, if any. */ - if (acl->acl_cnt != 0) { + error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, + cnp->cn_thread); + switch (error) { + case 0: + /* + * Retrieved a default ACL, so merge mode and ACL if + * necessary. + */ + if (acl->acl_cnt != 0) { + /* + * Two possible ways for default ACL to not + * be present. First, the EA can be + * undefined, or second, the default ACL can + * be blank. If it's blank, fall through to + * the it's not defined case. + */ + ip->i_mode = mode; + DIP(ip, i_mode) = mode; + ufs_sync_acl_from_inode(ip, acl); + break; + } + /* FALLTHROUGH */ + + case EOPNOTSUPP: /* - * Two possible ways for default ACL to not be - * present. First, the EA can be undefined, - * or second, the default ACL can be blank. - * If it's blank, fall through to the it's - * not defined case. + * Just use the mode as-is. */ ip->i_mode = mode; DIP(ip, i_mode) = mode; - ufs_sync_acl_from_inode(ip, acl); + FREE(acl, M_ACL); + acl = NULL; break; + + default: + UFS_VFREE(tvp, ip->i_number, mode); + vput(tvp); + FREE(acl, M_ACL); + acl = NULL; + return (error); } - - case EOPNOTSUPP: - /* - * Just use the mode as-is. - */ + } else { +#endif ip->i_mode = mode; DIP(ip, i_mode) = mode; - FREE(acl, M_ACL); - acl = NULL; - break; - - default: - UFS_VFREE(tvp, ip->i_number, mode); - vput(tvp); - FREE(acl, M_ACL); - acl = NULL; - return (error); +#ifdef UFS_ACL } -#else /* !UFS_ACL */ - ip->i_mode = mode; - DIP(ip, i_mode) = mode; -#endif /* !UFS_ACL */ +#endif tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ ip->i_effnlink = 1; ip->i_nlink = 1; |