1*8565Sroot /* vfs_vnops.c 4.28 82/10/17 */ 218Sbill 318Sbill #include "../h/param.h" 418Sbill #include "../h/systm.h" 518Sbill #include "../h/dir.h" 618Sbill #include "../h/user.h" 76569Smckusic #include "../h/fs.h" 818Sbill #include "../h/file.h" 918Sbill #include "../h/conf.h" 1018Sbill #include "../h/inode.h" 1118Sbill #include "../h/reg.h" 1218Sbill #include "../h/acct.h" 132302Skre #include "../h/mount.h" 144914Swnj #include "../h/socket.h" 154914Swnj #include "../h/socketvar.h" 165581Swnj #include "../h/proc.h" 1718Sbill 1818Sbill /* 194817Swnj * Openi called to allow handler 2018Sbill * of special files to initialize and 2118Sbill * validate before actual IO. 2218Sbill */ 237654Ssam openi(ip, mode) 244817Swnj register struct inode *ip; 2518Sbill { 26*8565Sroot dev_t dev = (dev_t)ip->i_rdev; 27*8565Sroot register u_int maj = major(dev); 2818Sbill 294817Swnj switch (ip->i_mode&IFMT) { 3018Sbill 3118Sbill case IFCHR: 324817Swnj if (maj >= nchrdev) 33*8565Sroot return (ENXIO); 34*8565Sroot return ((*cdevsw[maj].d_open)(dev, mode)); 3518Sbill 3618Sbill case IFBLK: 374817Swnj if (maj >= nblkdev) 38*8565Sroot return (ENXIO); 39*8565Sroot return ((*bdevsw[maj].d_open)(dev, mode)); 4018Sbill } 41*8565Sroot return (0); 4218Sbill } 4318Sbill 4418Sbill /* 4518Sbill * Check mode permission on inode pointer. 4618Sbill * Mode is READ, WRITE or EXEC. 4718Sbill * In the case of WRITE, the 4818Sbill * read-only status of the file 4918Sbill * system is checked. 5018Sbill * Also in WRITE, prototype text 5118Sbill * segments cannot be written. 5218Sbill * The mode is shifted to select 5318Sbill * the owner/group/other fields. 5418Sbill * The super user is granted all 5518Sbill * permissions. 5618Sbill */ 5718Sbill access(ip, mode) 584817Swnj register struct inode *ip; 594817Swnj int mode; 6018Sbill { 6118Sbill register m; 627867Sroot register int *gp; 6318Sbill 6418Sbill m = mode; 654817Swnj if (m == IWRITE) { 666569Smckusic if (ip->i_fs->fs_ronly != 0) { 6718Sbill u.u_error = EROFS; 684817Swnj return (1); 6918Sbill } 7018Sbill if (ip->i_flag&ITEXT) /* try to free text */ 7118Sbill xrele(ip); 724817Swnj if (ip->i_flag & ITEXT) { 7318Sbill u.u_error = ETXTBSY; 744817Swnj return (1); 7518Sbill } 7618Sbill } 774817Swnj if (u.u_uid == 0) 784817Swnj return (0); 794817Swnj if (u.u_uid != ip->i_uid) { 8018Sbill m >>= 3; 817867Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 827867Sroot if (ip->i_gid != *gp) 837867Sroot goto found; 847867Sroot m >>= 3; 857867Sroot found: 867867Sroot ; 8718Sbill } 884817Swnj if ((ip->i_mode&m) != 0) 894817Swnj return (0); 9018Sbill u.u_error = EACCES; 914817Swnj return (1); 9218Sbill } 9318Sbill 9418Sbill /* 9518Sbill * Look up a pathname and test if 9618Sbill * the resultant inode is owned by the 9718Sbill * current user. 9818Sbill * If not, try for super-user. 9918Sbill * If permission is granted, 10018Sbill * return inode pointer. 10118Sbill */ 10218Sbill struct inode * 1035990Swnj owner(follow) 1045990Swnj int follow; 10518Sbill { 10618Sbill register struct inode *ip; 10718Sbill 1085990Swnj ip = namei(uchar, 0, follow); 1094817Swnj if (ip == NULL) 1104817Swnj return (NULL); 1114817Swnj if (u.u_uid == ip->i_uid) 1124817Swnj return (ip); 1134817Swnj if (suser()) 1144817Swnj return (ip); 11518Sbill iput(ip); 1164817Swnj return (NULL); 11718Sbill } 11818Sbill 11918Sbill /* 12018Sbill * Test if the current user is the 12118Sbill * super user. 12218Sbill */ 12318Sbill suser() 12418Sbill { 12518Sbill 1264817Swnj if (u.u_uid == 0) { 12718Sbill u.u_acflag |= ASU; 1284817Swnj return (1); 12918Sbill } 13018Sbill u.u_error = EPERM; 1314817Swnj return (0); 13218Sbill } 133