1*17099Sbloom /* vfs_vnops.c 6.3 84/08/29 */ 218Sbill 39764Ssam #include "../machine/reg.h" 49764Ssam 5*17099Sbloom #include "param.h" 6*17099Sbloom #include "systm.h" 7*17099Sbloom #include "dir.h" 8*17099Sbloom #include "user.h" 9*17099Sbloom #include "fs.h" 10*17099Sbloom #include "file.h" 11*17099Sbloom #include "conf.h" 12*17099Sbloom #include "inode.h" 13*17099Sbloom #include "acct.h" 14*17099Sbloom #include "mount.h" 15*17099Sbloom #include "socket.h" 16*17099Sbloom #include "socketvar.h" 17*17099Sbloom #include "proc.h" 1818Sbill 1918Sbill /* 2018Sbill * Check mode permission on inode pointer. 2118Sbill * Mode is READ, WRITE or EXEC. 2218Sbill * In the case of WRITE, the 2318Sbill * read-only status of the file 2418Sbill * system is checked. 2518Sbill * Also in WRITE, prototype text 2618Sbill * segments cannot be written. 2718Sbill * The mode is shifted to select 2818Sbill * the owner/group/other fields. 2918Sbill * The super user is granted all 3018Sbill * permissions. 3118Sbill */ 3218Sbill access(ip, mode) 334817Swnj register struct inode *ip; 344817Swnj int mode; 3518Sbill { 3618Sbill register m; 377867Sroot register int *gp; 3818Sbill 3918Sbill m = mode; 404817Swnj if (m == IWRITE) { 4111162Ssam /* 4211162Ssam * Disallow write attempts on read-only 4311162Ssam * file systems; unless the file is a block 4411162Ssam * or character device resident on the 4511162Ssam * file system. 4611162Ssam */ 476569Smckusic if (ip->i_fs->fs_ronly != 0) { 488956Sroot if ((ip->i_mode & IFMT) != IFCHR && 498956Sroot (ip->i_mode & IFMT) != IFBLK) { 508956Sroot u.u_error = EROFS; 518956Sroot return (1); 528956Sroot } 5318Sbill } 5411162Ssam /* 5511162Ssam * If there's shared text associated with 5611162Ssam * the inode, try to free it up once. If 5711162Ssam * we fail, we can't allow writing. 5811162Ssam */ 5911162Ssam if (ip->i_flag&ITEXT) 6018Sbill xrele(ip); 614817Swnj if (ip->i_flag & ITEXT) { 6218Sbill u.u_error = ETXTBSY; 634817Swnj return (1); 6418Sbill } 6518Sbill } 6611162Ssam /* 6711162Ssam * If you're the super-user, 6811162Ssam * you always get access. 6911162Ssam */ 704817Swnj if (u.u_uid == 0) 714817Swnj return (0); 7211162Ssam /* 7311162Ssam * Access check is based on only 7411162Ssam * one of owner, group, public. 7511162Ssam * If not owner, then check group. 7611162Ssam * If not a member of the group, then 7711162Ssam * check public access. 7811162Ssam */ 794817Swnj if (u.u_uid != ip->i_uid) { 8018Sbill m >>= 3; 8111162Ssam if (u.u_gid == ip->i_gid) 8211162Ssam goto found; 8311812Ssam gp = u.u_groups; 8411812Ssam for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) 8510044Ssam if (ip->i_gid == *gp) 867867Sroot goto found; 877867Sroot m >>= 3; 887867Sroot found: 897867Sroot ; 9018Sbill } 914817Swnj if ((ip->i_mode&m) != 0) 924817Swnj return (0); 9318Sbill u.u_error = EACCES; 944817Swnj return (1); 9518Sbill } 9618Sbill 9718Sbill /* 9818Sbill * Look up a pathname and test if 9918Sbill * the resultant inode is owned by the 10018Sbill * current user. 10118Sbill * If not, try for super-user. 10218Sbill * If permission is granted, 10318Sbill * return inode pointer. 10418Sbill */ 10518Sbill struct inode * 10616693Smckusick owner(fname, follow) 10716693Smckusick caddr_t fname; 1085990Swnj int follow; 10918Sbill { 11018Sbill register struct inode *ip; 11116693Smckusick register struct nameidata *ndp = &u.u_nd; 11218Sbill 11316693Smckusick ndp->ni_nameiop = LOOKUP | follow; 11416693Smckusick ndp->ni_segflg = UIO_USERSPACE; 11516693Smckusick ndp->ni_dirp = fname; 11616693Smckusick ip = namei(ndp); 1174817Swnj if (ip == NULL) 1184817Swnj return (NULL); 1194817Swnj if (u.u_uid == ip->i_uid) 1204817Swnj return (ip); 1214817Swnj if (suser()) 1224817Swnj return (ip); 12318Sbill iput(ip); 1244817Swnj return (NULL); 12518Sbill } 12618Sbill 12718Sbill /* 12818Sbill * Test if the current user is the 12918Sbill * super user. 13018Sbill */ 13118Sbill suser() 13218Sbill { 13318Sbill 1344817Swnj if (u.u_uid == 0) { 13518Sbill u.u_acflag |= ASU; 1364817Swnj return (1); 13718Sbill } 13818Sbill u.u_error = EPERM; 1394817Swnj return (0); 14018Sbill } 141