/* * Read POSIX.1e ACL from an EA. Return error if its not found * or if any other error has occurred. */ static int ufs_get_oldacl(acl_type_t type, struct oldacl *old, struct vnode *vp, struct thread *td) { int error, len; struct inode *ip = VTOI(vp); len = sizeof(*old); switch (type) { case ACL_TYPE_ACCESS: error = vn_extattr_get(vp, IO_NODELOCKED, POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE, POSIX1E_ACL_ACCESS_EXTATTR_NAME, &len, (char *) old, td); break; case ACL_TYPE_DEFAULT: if (vp->v_type != VDIR) return (EINVAL); error = vn_extattr_get(vp, IO_NODELOCKED, POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE, POSIX1E_ACL_DEFAULT_EXTATTR_NAME, &len, (char *) old, td); break; default: return (EINVAL); } if (error != 0) return (error); if (len != sizeof(*old)) { /* * A short (or long) read, meaning that for some reason * the ACL is corrupted. Return EPERM since the object * DAC protections are unsafe. */ printf("ufs_get_oldacl(): Loaded invalid ACL " "(len = %d), inumber %ju on %s\n", len, (uintmax_t)ip->i_number, ip->i_fs->fs_fsmnt); return (EPERM); } return (0); }
/* * Retrieve NFSv4 ACL, skipping access checks. Must be used in UFS code * instead of VOP_GETACL() when we don't want to be restricted by the user * not having ACL_READ_ACL permission, e.g. when calculating inherited ACL * or in ufs_vnops.c:ufs_accessx(). */ int ufs_getacl_nfs4_internal(struct vnode *vp, struct acl *aclp, struct thread *td) { int error, len; struct inode *ip = VTOI(vp); len = sizeof(*aclp); bzero(aclp, len); error = vn_extattr_get(vp, IO_NODELOCKED, NFS4_ACL_EXTATTR_NAMESPACE, NFS4_ACL_EXTATTR_NAME, &len, (char *) aclp, td); aclp->acl_maxcnt = ACL_MAX_ENTRIES; if (error == ENOATTR) { /* * Legitimately no ACL set on object, purely * emulate it through the inode. */ acl_nfs4_sync_acl_from_mode(aclp, ip->i_mode, ip->i_uid); return (0); } if (error) return (error); if (len != sizeof(*aclp)) { /* * A short (or long) read, meaning that for * some reason the ACL is corrupted. Return * EPERM since the object DAC protections * are unsafe. */ printf("ufs_getacl_nfs4(): Loaded invalid ACL (" "%d bytes), inumber %ju on %s\n", len, (uintmax_t)ip->i_number, ip->i_fs->fs_fsmnt); return (EPERM); } error = acl_nfs4_check(aclp, vp->v_type == VDIR); if (error) { printf("ufs_getacl_nfs4(): Loaded invalid ACL " "(failed acl_nfs4_check), inumber %ju on %s\n", (uintmax_t)ip->i_number, ip->i_fs->fs_fsmnt); return (EPERM); } return (0); }
static int verify_file(struct ucred *cred, struct vnode *vp) { char buffer[256]; char hash[SHA256_DIGEST_LENGTH > uECC_BYTES ? SHA256_DIGEST_LENGTH : uECC_BYTES]; char signature[2*uECC_BYTES]; int error, len; ssize_t resid; off_t i, size; SHA256_CTX ctx; struct stat stat; i = 0; error = vn_stat(vp, &stat, cred, NOCRED, curthread); size = stat.st_size; if (error) return (EPERM); len = sizeof(signature); error = vn_extattr_get(vp, IO_NODELOCKED, EXTATTR_NAMESPACE_SYSTEM, "signature", &len, signature, curthread); if (error) return (EPERM); #ifdef DEBUG printf("Signature: "); print_hex(signature, sizeof(signature)); #endif SHA256_Init(&ctx); while(i < size && !error) { len = size - i > sizeof(buffer) ? sizeof(buffer) : size - i; error = vn_rdwr(UIO_READ, vp, buffer, len, i, UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED, &resid, curthread); SHA256_Update(&ctx, buffer, len); i += len; } if (error) return (EPERM); SHA256_Final(hash, &ctx); #ifdef DEBUG printf("Hash: "); print_hex(hash, sizeof(hash)); #endif if (!uECC_verify(pubkey, hash, signature)) return (EPERM); return (0); }