static int udf_access(struct vop_access_args *a) { struct vnode *vp; struct udf_node *node; accmode_t accmode; mode_t mode; vp = a->a_vp; node = VTON(vp); accmode = a->a_accmode; if (accmode & VWRITE) { switch (vp->v_type) { case VDIR: case VLNK: case VREG: return (EROFS); /* NOT REACHED */ default: break; } } mode = udf_permtomode(node); return (vaccess(vp->v_type, mode, node->fentry->uid, node->fentry->gid, accmode, a->a_cred, NULL)); }
static int shm_chmod(struct file *fp, mode_t mode, struct ucred *active_cred, struct thread *td) { struct shmfd *shmfd; int error; error = 0; shmfd = fp->f_data; mtx_lock(&shm_timestamp_lock); /* * SUSv4 says that x bits of permission need not be affected. * Be consistent with our shm_open there. */ #ifdef MAC error = mac_posixshm_check_setmode(active_cred, shmfd, mode); if (error != 0) goto out; #endif error = vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid, shmfd->shm_gid, VADMIN, active_cred, NULL); if (error != 0) goto out; shmfd->shm_mode = mode & ACCESSPERMS; out: mtx_unlock(&shm_timestamp_lock); return (error); }
int ipcperm(struct ucred *cred, struct ipc_perm *perm, int mode) { if (mode == IPC_M) { if (cred->cr_uid == 0 || cred->cr_uid == perm->uid || cred->cr_uid == perm->cuid) return (0); return (EPERM); } if (vaccess(perm->mode, perm->uid, perm->gid, mode, cred) == 0 || vaccess(perm->mode, perm->cuid, perm->cgid, mode, cred) == 0) return (0); return (EACCES); }
/* * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. * The mode is shifted to select the owner/group/other fields. The * super user is granted all permissions. */ int cd9660_access(void *v) { struct vop_access_args *ap = v; struct iso_node *ip = VTOI(ap->a_vp); return (vaccess(ap->a_vp->v_type, ip->inode.iso_mode & ALLPERMS, ip->inode.iso_uid, ip->inode.iso_gid, ap->a_mode, ap->a_cred)); }
/* * Determine if the credentials have sufficient permissions for read * and write access. */ static int ksem_access(struct ksem *ks, struct ucred *ucred) { int error; error = vaccess(VREG, ks->ks_mode, ks->ks_uid, ks->ks_gid, VREAD | VWRITE, ucred, NULL); if (error) error = priv_check_cred(ucred, PRIV_SEM_WRITE, 0); return (error); }
int tmpfs_access(struct vop_access_args *v) { struct vnode *vp = v->a_vp; accmode_t accmode = v->a_accmode; struct ucred *cred = v->a_cred; int error; struct tmpfs_node *node; MPASS(VOP_ISLOCKED(vp)); node = VP_TO_TMPFS_NODE(vp); switch (vp->v_type) { case VDIR: /* FALLTHROUGH */ case VLNK: /* FALLTHROUGH */ case VREG: if (accmode & VWRITE && vp->v_mount->mnt_flag & MNT_RDONLY) { error = EROFS; goto out; } break; case VBLK: /* FALLTHROUGH */ case VCHR: /* FALLTHROUGH */ case VSOCK: /* FALLTHROUGH */ case VFIFO: break; default: error = EINVAL; goto out; } if (accmode & VWRITE && node->tn_flags & IMMUTABLE) { error = EPERM; goto out; } error = vaccess(vp->v_type, node->tn_mode, node->tn_uid, node->tn_gid, accmode, cred, NULL); out: MPASS(VOP_ISLOCKED(vp)); return error; }
/* * implement access checking. * * actually, the check for super-user is slightly * broken since it will allow read access to write-only * objects. this doesn't cause any particular trouble * but does mean that the i/o entry points need to check * that the operation really does make sense. */ int procfs_access(void *v) { struct vop_access_args *ap = v; struct vattr va; int error; if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0) return (error); return (vaccess(ap->a_vp->v_type, va.va_mode, va.va_uid, va.va_gid, ap->a_mode, ap->a_cred)); }
/* * Determine if the credentials have sufficient permissions for a * specified combination of FREAD and FWRITE. */ static int shm_access(struct shmfd *shmfd, struct ucred *ucred, int flags) { accmode_t accmode; accmode = 0; if (flags & FREAD) accmode |= VREAD; if (flags & FWRITE) accmode |= VWRITE; return (vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid, shmfd->shm_gid, accmode, ucred, NULL)); }
int ext2fs_access(void *v) { struct vop_access_args *ap = v; struct vnode *vp = ap->a_vp; struct inode *ip = VTOI(vp); mode_t mode = ap->a_mode; /* If immutable bit set, nobody gets to write it. */ if ((mode & VWRITE) && (ip->i_e2fs_flags & EXT2_IMMUTABLE)) return (EPERM); return (vaccess(vp->v_type, ip->i_e2fs_mode, ip->i_e2fs_uid, ip->i_e2fs_gid, mode, ap->a_cred)); }
/* * implement access checking. * * actually, the check for super-user is slightly * broken since it will allow read access to write-only * objects. this doesn't cause any particular trouble * but does mean that the i/o entry points need to check * that the operation really does make sense. */ int ptyfs_access(void *v) { struct vop_access_args /* { struct vnode *a_vp; int a_mode; kauth_cred_t a_cred; } */ *ap = v; struct vattr va; int error; if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0) return error; return vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid, ap->a_mode, ap->a_cred); }
/* * Determine if the credentials have sufficient permissions for a * specified combination of FREAD and FWRITE. */ static int shm_access(struct shmfd *shmfd, struct ucred *ucred, int flags) { accmode_t accmode; int error; accmode = 0; if (flags & FREAD) accmode |= VREAD; if (flags & FWRITE) accmode |= VWRITE; mtx_lock(&shm_timestamp_lock); error = vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid, shmfd->shm_gid, accmode, ucred, NULL); mtx_unlock(&shm_timestamp_lock); return (error); }
static int p9fs_access(struct vop_access_args *ap) { struct p9fs_node *np = ap->a_vp->v_data; int accmode = ap->a_accmode; struct vattr vattr; int error; /* Read-only filesystem check. */ if ((accmode & VMODIFY_PERMS) != 0 && (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) != 0) { switch (ap->a_vp->v_type) { case VDIR: case VLNK: case VREG: error = EROFS; goto out; default: break; } } error = vfs_unixify_accmode(&accmode); if (error != 0) goto out; if (accmode == 0) goto out; /* * We have some access mode to check. * * XXX In cooperation with p9fs_{open,getattr}(), can this metadata * be cached in a reasonable fashion? */ error = p9fs_client_stat(np->p9n_session, np->p9n_fid, &vattr); if (error != 0) goto out; error = vaccess(ap->a_vp->v_type, vattr.va_mode, vattr.va_uid, vattr.va_gid, accmode, ap->a_cred, NULL); out: printf("%s(fid %d) ret %d\n", __func__, np->p9n_fid, error); return (error); }
/* * Verify permissions */ static int pfs_access(struct vop_access_args *va) { struct vnode *vn = va->a_vp; struct pfs_vdata *pvd = vn->v_data; struct vattr vattr; int error; PFS_TRACE(("%s", pvd->pvd_pn->pn_name)); (void)pvd; error = VOP_GETATTR(vn, &vattr, va->a_cred, va->a_td); if (error) PFS_RETURN (error); error = vaccess(vn->v_type, vattr.va_mode, vattr.va_uid, vattr.va_gid, va->a_mode, va->a_cred, NULL); PFS_RETURN (error); }
int ufs_access(void *v) { struct vop_access_args *ap = v; struct vnode *vp = ap->a_vp; struct inode *ip = VTOI(vp); mode_t mode = ap->a_mode; /* * Disallow write attempts on read-only file systems; * unless the file is a socket, fifo, or a block or * character device resident on the file system. */ if (mode & VWRITE) { switch (vp->v_type) { int error; case VDIR: case VLNK: case VREG: if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); if ((error = getinoquota(ip)) != 0) return (error); break; case VBAD: case VBLK: case VCHR: case VSOCK: case VFIFO: case VNON: break; } } /* If immutable bit set, nobody gets to write it. */ if ((mode & VWRITE) && (DIP(ip, flags) & IMMUTABLE)) return (EPERM); return (vaccess(vp->v_type, DIP(ip, mode), DIP(ip, uid), DIP(ip, gid), mode, ap->a_cred)); }
/*VARARGS1*/ void vassign(value_t *p, char *v) { if (!vaccess(p->v_access, WRITE)) { printf("access denied\r\n"); return; } switch (p->v_type&TMASK) { case STRING: if (p->v_value && equal(p->v_value, v)) return; if (!(p->v_type&(ENVIRON|INIT))) free(p->v_value); if ((p->v_value = malloc(size(v)+1)) == NULL) { printf("out of core\r\n"); return; } p->v_type &= ~(ENVIRON|INIT); strcpy(p->v_value, v); break; case NUMBER: if (number(p->v_value) == number(v)) return; number(p->v_value) = number(v); break; case BOOL: if (boolean(p->v_value) == (*v != '!')) return; boolean(p->v_value) = (*v != '!'); break; case CHAR: if (character(p->v_value) == *v) return; character(p->v_value) = *v; } p->v_access |= CHANGED; }
static int reiserfs_access(struct vop_access_args *ap) { int error; struct vnode *vp = ap->a_vp; struct reiserfs_node *ip = VTOI(vp); accmode_t accmode = ap->a_accmode; /* * Disallow write attempts on read-only file systems; unless the file * is a socket, fifo, or a block or character device resident on the * file system. */ if (accmode & VWRITE) { switch (vp->v_type) { case VDIR: case VLNK: case VREG: if (vp->v_mount->mnt_flag & MNT_RDONLY) { reiserfs_log(LOG_DEBUG, "no write access (read-only fs)\n"); return (EROFS); } break; default: break; } } /* If immutable bit set, nobody gets to write it. */ if ((accmode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) { reiserfs_log(LOG_DEBUG, "no write access (immutable)\n"); return (EPERM); } error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, ap->a_accmode, ap->a_cred, NULL); return (error); }
int msdosfs_access(void *v) { struct vop_access_args *ap = v; struct denode *dep = VTODE(ap->a_vp); struct msdosfsmount *pmp = dep->de_pmp; mode_t dosmode; dosmode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH); if ((dep->de_Attributes & ATTR_READONLY) == 0) dosmode |= (S_IWUSR|S_IWGRP|S_IWOTH); dosmode &= pmp->pm_mask; if (dep->de_Attributes & ATTR_DIRECTORY && pmp->pm_flags & MSDOSFSMNT_ALLOWDIRX) { dosmode |= (dosmode & S_IRUSR) ? S_IXUSR : 0; dosmode |= (dosmode & S_IRGRP) ? S_IXGRP : 0; dosmode |= (dosmode & S_IROTH) ? S_IXOTH : 0; } return (vaccess(ap->a_vp->v_type, dosmode, pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred)); }
void vlex(char *s) { value_t *p; char *cp; if (equal(s, "all")) { for (p = vtable; p->v_name; p++) if (vaccess(p->v_access, READ)) vprint(p); } else { do { if ((cp = vinterp(s, ' '))) cp++; vtoken(s); s = cp; } while (s); } if (col > 0) { printf("\r\n"); col = 0; } }
/*VARARGS1*/ static void vassign(value_t *p, char *v) { if (!vaccess(p->v_access, WRITE)) { printf("access denied\r\n"); return; } switch (p->v_type&TMASK) { case STRING: if (p->v_value && equal(p->v_value, v)) return; if (!(p->v_type&(ENVIRON|INIT))) free(p->v_value); if ((p->v_value = strdup(v)) == NOSTR) { printf("out of core\r\n"); return; } p->v_type &= ~(ENVIRON|INIT); break; case NUMBER: if (number(p->v_value) == number(v)) return; setnumber(p->v_value, number(v)); break; case BOOL: if (boolean(p->v_value) == (*v != '!')) return; setboolean(p->v_value, (*v != '!')); break; case CHAR: if (character(p->v_value) == *v) return; setcharacter(p->v_value, *v); } p->v_access |= CHANGED; }
static int ext2_access(struct vop_access_args *ap) { struct vnode *vp = ap->a_vp; struct inode *ip = VTOI(vp); accmode_t accmode = ap->a_accmode; int error; if (vp->v_type == VBLK || vp->v_type == VCHR) return (EOPNOTSUPP); /* * Disallow write attempts on read-only file systems; * unless the file is a socket, fifo, or a block or * character device resident on the file system. */ if (accmode & VWRITE) { switch (vp->v_type) { case VDIR: case VLNK: case VREG: if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); break; default: break; } } /* If immutable bit set, nobody gets to write it. */ if ((accmode & VWRITE) && (ip->i_flags & (SF_IMMUTABLE | SF_SNAPSHOT))) return (EPERM); error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, ap->a_accmode, ap->a_cred, NULL); return (error); }
static void vtoken(char *s) { value_t *p; char *cp; if ((cp = strchr(s, '='))) { *cp = '\0'; if ((p = vlookup(s))) { cp++; if (p->v_type&NUMBER) vassign(p, (char *)(intptr_t)atoi(cp)); else { if (strcmp(s, "record") == 0) cp = expand(cp); vassign(p, cp); } return; } } else if ((cp = strchr(s, '?'))) { *cp = '\0'; if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { vprint(p); return; } } else { if (*s != '!') p = vlookup(s); else p = vlookup(s+1); if (p != NOVAL) { vassign(p, s); return; } } printf("%s: unknown variable\r\n", s); }
static int ksem_chmod(struct file *fp, mode_t mode, struct ucred *active_cred, struct thread *td) { struct ksem *ks; int error; error = 0; ks = fp->f_data; mtx_lock(&sem_lock); #ifdef MAC error = mac_posixsem_check_setmode(active_cred, ks, mode); if (error != 0) goto out; #endif error = vaccess(VREG, ks->ks_mode, ks->ks_uid, ks->ks_gid, VADMIN, active_cred, NULL); if (error != 0) goto out; ks->ks_mode = mode & ACCESSPERMS; out: mtx_unlock(&sem_lock); return (error); }
int fusefs_access(void *v) { struct vop_access_args *ap; struct fusefs_node *ip; struct fusefs_mnt *fmp; struct fusebuf *fbuf; struct proc *p; uint32_t mask = 0; int error = 0; DPRINTF("fusefs_access\n"); ap = v; p = ap->a_p; ip = VTOI(ap->a_vp); fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump; if (!fmp->sess_init || (fmp->undef_op & UNDEF_ACCESS)) goto system_check; if (ap->a_vp->v_type == VLNK) goto system_check; if (ap->a_vp->v_type == VREG && (ap->a_mode & VWRITE & VEXEC)) goto system_check; if ((ap->a_mode & VWRITE) && (fmp->mp->mnt_flag & MNT_RDONLY)) return (EACCES); if ((ap->a_mode & VWRITE) != 0) mask |= 0x2; if ((ap->a_mode & VREAD) != 0) mask |= 0x4; if ((ap->a_mode & VEXEC) != 0) mask |= 0x1; fbuf = fb_setup(FUSEFDSIZE, ip->ufs_ino.i_number, FBT_ACCESS, p); fbuf->fb_io_mode = mask; error = fb_queue(fmp->dev, fbuf); if (error) { if (error == ENOSYS) { fmp->undef_op |= UNDEF_ACCESS; pool_put(&fusefs_fbuf_pool, fbuf); goto system_check; } DPRINTF("access error %i\n", error); pool_put(&fusefs_fbuf_pool, fbuf); return (error); } pool_put(&fusefs_fbuf_pool, fbuf); return (error); system_check: return (vaccess(ap->a_vp->v_type, ip->cached_attrs.va_mode & ALLPERMS, ip->cached_attrs.va_uid, ip->cached_attrs.va_gid, ap->a_mode, ap->a_cred)); }
int fusefs_access(void *v) { struct vop_access_args *ap; struct fusefs_node *ip; struct fusefs_mnt *fmp; struct fusebuf *fbuf; struct ucred *cred; struct vattr vattr; struct proc *p; uint32_t mask = 0; int error = 0; ap = v; p = curproc; cred = p->p_ucred; ip = VTOI(ap->a_vp); fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump; if (!fmp->sess_init || (fmp->undef_op & UNDEF_ACCESS)) goto system_check; if (ap->a_vp->v_type == VLNK) goto system_check; if (ap->a_vp->v_type == VREG && (ap->a_mode & VWRITE & VEXEC)) goto system_check; if ((ap->a_mode & VWRITE) && (fmp->mp->mnt_flag & MNT_RDONLY)) return (EACCES); if ((ap->a_mode & VWRITE) != 0) mask |= 0x2; if ((ap->a_mode & VREAD) != 0) mask |= 0x4; if ((ap->a_mode & VEXEC) != 0) mask |= 0x1; fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_ACCESS, p); fbuf->fb_io_mode = mask; error = fb_queue(fmp->dev, fbuf); if (error) { if (error == ENOSYS) { fmp->undef_op |= UNDEF_ACCESS; fb_delete(fbuf); goto system_check; } printf("fusefs: access error %i\n", error); fb_delete(fbuf); return (error); } fb_delete(fbuf); return (error); system_check: if ((error = VOP_GETATTR(ap->a_vp, &vattr, cred)) != 0) return (error); return (vaccess(ap->a_vp->v_type, vattr.va_mode & ALLPERMS, vattr.va_uid, vattr.va_gid, ap->a_mode, ap->a_cred)); }