1*16693Smckusick /* vfs_vnops.c 6.2 84/07/08 */ 218Sbill 39764Ssam #include "../machine/reg.h" 49764Ssam 518Sbill #include "../h/param.h" 618Sbill #include "../h/systm.h" 718Sbill #include "../h/dir.h" 818Sbill #include "../h/user.h" 96569Smckusic #include "../h/fs.h" 1018Sbill #include "../h/file.h" 1118Sbill #include "../h/conf.h" 1218Sbill #include "../h/inode.h" 1318Sbill #include "../h/acct.h" 142302Skre #include "../h/mount.h" 154914Swnj #include "../h/socket.h" 164914Swnj #include "../h/socketvar.h" 175581Swnj #include "../h/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 * 106*16693Smckusick owner(fname, follow) 107*16693Smckusick caddr_t fname; 1085990Swnj int follow; 10918Sbill { 11018Sbill register struct inode *ip; 111*16693Smckusick register struct nameidata *ndp = &u.u_nd; 11218Sbill 113*16693Smckusick ndp->ni_nameiop = LOOKUP | follow; 114*16693Smckusick ndp->ni_segflg = UIO_USERSPACE; 115*16693Smckusick ndp->ni_dirp = fname; 116*16693Smckusick 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