/* * Test for existence of default ACL attribute as efficiently as possible. */ int xfs_acl_vhasacl_default( xfs_vnode_t *vp) { int error; if (!VN_ISDIR(vp)) return 0; xfs_acl_get_attr(vp, NULL, _ACL_TYPE_DEFAULT, ATTR_KERNOVAL, &error); return (error == 0); }
/* * This function retrieves the parent directory's acl, processes it * and lets the child inherit the acl(s) that it should. */ int xfs_acl_inherit( xfs_vnode_t *vp, xfs_vattr_t *vap, xfs_acl_t *pdaclp) { xfs_acl_t *cacl; int error = 0; int basicperms = 0; /* * If the parent does not have a default ACL, or it's an * invalid ACL, we're done. */ if (!vp) return 0; if (!pdaclp || xfs_acl_invalid(pdaclp)) return 0; /* * Copy the default ACL of the containing directory to * the access ACL of the new file and use the mode that * was passed in to set up the correct initial values for * the u::,g::[m::], and o:: entries. This is what makes * umask() "work" with ACL's. */ if (!(_ACL_ALLOC(cacl))) return ENOMEM; memcpy(cacl, pdaclp, sizeof(xfs_acl_t)); xfs_acl_filter_mode(vap->va_mode, cacl); xfs_acl_setmode(vp, cacl, &basicperms); /* * Set the Default and Access ACL on the file. The mode is already * set on the file, so we don't need to worry about that. * * If the new file is a directory, its default ACL is a copy of * the containing directory's default ACL. */ if (VN_ISDIR(vp)) xfs_acl_set_attr(vp, pdaclp, _ACL_TYPE_DEFAULT, &error); if (!error && !basicperms) xfs_acl_set_attr(vp, cacl, _ACL_TYPE_ACCESS, &error); _ACL_FREE(cacl); return error; }
STATIC int xfs_acl_allow_set( xfs_vnode_t *vp, int kind) { xfs_vattr_t va; int error; if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) return EPERM; if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) return ENOTDIR; if (vp->v_vfsp->vfs_flag & VFS_RDONLY) return EROFS; va.va_mask = XFS_AT_UID; XVOP_GETATTR(vp, &va, 0, NULL, error); if (error) return error; if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) return EPERM; return error; }
STATIC int xfs_acl_allow_set( bhv_vnode_t *vp, int kind) { xfs_inode_t *ip = xfs_vtoi(vp); bhv_vattr_t va; int error; if (vp->i_flags & (S_IMMUTABLE|S_APPEND)) return EPERM; if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) return ENOTDIR; if (vp->i_sb->s_flags & MS_RDONLY) return EROFS; va.va_mask = XFS_AT_UID; error = xfs_getattr(ip, &va, 0); if (error) return error; if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) return EPERM; return error; }