/* * Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)ufs_fio.c 7.1 (Berkeley) 6/5/86 */ #include "../machine/reg.h" #include "param.h" #include "systm.h" #include "dir.h" #include "user.h" #include "fs.h" #include "file.h" #include "conf.h" #include "inode.h" #include "acct.h" #include "mount.h" #include "socket.h" #include "socketvar.h" #include "proc.h" /* * Check mode permission on inode pointer. * Mode is READ, WRITE or EXEC. * In the case of WRITE, the * read-only status of the file * system is checked. * Also in WRITE, prototype text * segments cannot be written. * The mode is shifted to select * the owner/group/other fields. * The super user is granted all * permissions. */ access(ip, mode) register struct inode *ip; int mode; { register m; register gid_t *gp; m = mode; if (m == IWRITE) { /* * Disallow write attempts on read-only * file systems; unless the file is a block * or character device resident on the * file system. */ if (ip->i_fs->fs_ronly != 0) { if ((ip->i_mode & IFMT) != IFCHR && (ip->i_mode & IFMT) != IFBLK) { u.u_error = EROFS; return (1); } } /* * If there's shared text associated with * the inode, try to free it up once. If * we fail, we can't allow writing. */ if (ip->i_flag&ITEXT) xrele(ip); if (ip->i_flag & ITEXT) { u.u_error = ETXTBSY; return (1); } } /* * If you're the super-user, * you always get access. */ if (u.u_uid == 0) return (0); /* * Access check is based on only * one of owner, group, public. * If not owner, then check group. * If not a member of the group, then * check public access. */ if (u.u_uid != ip->i_uid) { m >>= 3; if (u.u_gid == ip->i_gid) goto found; gp = u.u_groups; for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) if (ip->i_gid == *gp) goto found; m >>= 3; found: ; } if ((ip->i_mode&m) != 0) return (0); u.u_error = EACCES; return (1); } /* * Look up a pathname and test if * the resultant inode is owned by the * current user. * If not, try for super-user. * If permission is granted, * return inode pointer. */ struct inode * owner(fname, follow) caddr_t fname; int follow; { register struct inode *ip; register struct nameidata *ndp = &u.u_nd; ndp->ni_nameiop = LOOKUP | follow; ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = fname; ip = namei(ndp); if (ip == NULL) return (NULL); if (u.u_uid == ip->i_uid) return (ip); if (suser()) return (ip); iput(ip); return (NULL); } /* * Test if the current user is the * super user. */ suser() { if (u.u_uid == 0) { u.u_acflag |= ASU; return (1); } u.u_error = EPERM; return (0); }